/* ARC (STD) -- Draw Arc/Circle */ /* ARC (STD) -- Kreisbogen/Kreis zeichnen */ /* -- INTENDED FOR KEY-CALL USE (:Center/Circle) -- */ /* // Copyright (c) 2005-2012 Oliver Bartels F+E, Muenchen // Author: Roman Ludwig // Changes History: // rl (120427) RELEASED FOR BAE V7.8. // rl (120427) RELEASED FOR BAE V7.8. // rl (101019) RELEASED FOR BAE V7.6. // rl (091020) RELEASED FOR BAE V7.4. // rl (081014) RELEASED FOR BAE V7.2. // rl (081014) ENHANCEMENT: // Added bae.ini settings writeback dialog button. // rl (071029) RELEASED FOR BAE V7.0. // rl (060829) RELEASED FOR BAE V6.8. // rl (050906) RELEASED FOR BAE V6.6. // rl (050322) ORIGINAL CODING. // // DESCRIPTION // // The arc User Language program designates the currently // active BAE menu function and performs a submenu interaction // for quick draw of an arc/circle. // Called while group movement the angle lock is disabled. // On activation outside a BAE menu function an operation mode // dialog box is displayed. This program must be configured for // implicit hotkey program call (e.g. or ). */ // Includes #include "pop.ulh" // User Language popup utilities // Enforce standard caller type #pragma ULCALLERSTD // Disable undo state request #pragma ULCALLERNOUNDO // INI file parameter name definitions #define PAR_ARCDRAW "ARCDRAW_STD" // Arc draw mode #define PAR_GDCORNERRAD "DCORNERR_GED" // GED default corner radius [m] #define PAR_SDCORNERRAD "DCORNERR_SCM" // SCM default corner radius [m] // Global definitions #define LAYERINV (-0x4000) // Invalid layer code #define SMALLVAL 0.00000001 // Small compare value #define SMALLANG 0.00001 // Small angle compare value #define BUTWIDTH 22.0 // Action button width #define COL2 26.0 // Second button column #define UL_POLYRND "polyrnd" // ULP: GED round polygon corners #define UL_TRACERND "tracernd" // ULP: GED round trace corners // Globals int ARCMODE = bae_iniintval(PAR_ARCDRAW,0); // Arc draw mode double ARCRADIUS /* Arc radius */; string ARCRADVNAME /* Arc radius variable name */; double px, py /* Pick coordinate */; double ix1, iy1 /* 1st input coordinate */; int ilay1 /* 1st input layer */; int ilay2 /* 2nd input layer */; double ix2, iy2 /* 2nd input coordinate */; int it2 /* 2nd input point type */; double ix3, iy3 /* 3rd input coordinate */; // Messages string UPRABORT = M_UPRABORT(); string UPRARCPARAM = M("Kreisbogenparameter","Arc/Circle Settings"); string UPRAMODE = M("Kreisbogenmodus selektieren!","Select arc mode!"); string UPRMODE1 = M("&Mittelpunkt setzen" ,"Set &Center"); string UPRMODE2 = M("&90 Grad Mittelpunkt" ,"&90 Degree Center"); string UPRMODE3 = M("&Innenbogen" ,"&Inner Corner"); string UPRMODE = M("Arbeitsmodus :","Process mode :"); string UPRARADD = M("Kreisbogenradius :","Arc Radius :"); string UPRARADM = M("Kreisbogenradius [mm] ? ","Arc Radius [mm] ? "); string UPRARADI = M("Kreisbogenradius [Inch] ? ", "Arc Radius [Inch] ? "); string UPRDUNIT = M("Einheiten :","Units :"); string UPRDUNITMM = M("mm","mm"); string UPRDUNITMIL = M("mil","mil"); string UPRTYPPOLY = M("Flaechen/Linien","Polygons"); string UPRTYPTRACE = M("Leiterbahnen","Traces"); string UPRCORN1 = M("Kreisboegen","Arcs"); string UPRCORN2 = M("Kreisboegen einzeln","Arcs Single"); string UPRCORN3 = M("45 Grad Knicke","45 Degrees Angles"); string UPRCORN4 = M("45 Grad Knicke einzeln", "45 Degrees Angles Single"); string UPRCORN5 = M("Boegen entfernen","Eliminate Arcs"); string UPRCORN6 = M("Einzelboegen entfernen","Eliminate Arcs Single"); string UPRCORN7 = M("45 Grad Knicke entfernen", "Eliminate 45 Degree Angles"); string UPRCORN8 = M("Einzel 45 Grad Knicke entfernen", "Eliminate 45 Degree Arcs Single"); string UPRCORN9 = M("Gruppe Kreisboegen","Group Arcs"); string UPRCORN10 = M("Gruppe 45 Grad Knicke", "Group 45 Degrees Angles"); string UPRCORN11 = M("Gruppe Boegen entfernen", "Group Eliminate Arcs"); string UPRCORN12 = M("Gruppe 45 Grad Knicke entfernen", "Group Eliminate 45 Degree Angles"); string ERRINPVAL = M_ERRINPVAL(); double PI = cvtangle(180.0,1,2) /* PI-value */; static int callertype=uliptype() /* Calling environment type */; // Main program void main() { // Test the interpreter type switch (callertype) { /* SCM */ case ULIPSCM : arc_scm(); break; /* GED */ case ULIPGED : arc_ged(); break; /* AR */ case ULIPAR : break; /* CAM */ case ULIPCAM : break; /* CED */ case ULIPCED : break; /* CV */ case ULIPCV : break; // Ignore on default default : break; } // Done } void arc_scm() /* // Draw arc at current SCM object */ { double gridx, gridy /* Input grid */; int inpmode /* Input mode */; // Get the current mouse position bae_wsmouse(px,py,0); bae_getinpgrid(gridx,gridy); // Get the corner radius if (varget(VAR_CORNERR,ARCRADIUS)) ARCRADIUS=bae_inidblval(PAR_SDCORNERRAD,0.0002); ARCRADVNAME=PAR_SDCORNERRAD; // Check if standalone call if (ulproginfo("",0,0)<=1 && bae_getactmenu()<0) { setarcmode(); exit(0); } // Get the currently active menu switch (bae_getactmenu()) { // Polygon edit functions case 500 : case 501 : case 502 : case 503 : case 507 : case 508 : case MNU_SCMGRPPOLY : break; case MNU_SCMMOVEGRP : case MNU_SCMCOPYGRP : case MNU_SCMLOADGRP : bae_setanglelock(0); exit(0); // Ignore on default default : exit(0); } // Check if input data available ilay1=LAYERINV; if (scm_getinputdata(ix1,iy1,0.0,ilay1,0.0,0.0,0.0, ilay2,inpmode,ix3,iy3,ix2,iy2,it2,0.0,0.0,0.0,0.0,0)!=0) exit(0); // Snap to input grid if (bae_getgridlock() && gridx!=0.0 && gridy!=0.0) { bae_storemouseiact(3,px,py,0,LMB); bae_inpoint(px,py,px,py,0); } // Draw the arc drawarc(1); } void arc_ged() /* // Draw arc at current GED object */ { double gridx, gridy /* Input grid */; int inpmode /* Input mode */; int dirsel /* Direction selection type */; // Get the current mouse position bae_wsmouse(px,py,0); bae_getinpgrid(gridx,gridy); // Get the corner radius if (varget(VAR_CORNERR,ARCRADIUS)) ARCRADIUS=bae_inidblval(PAR_GDCORNERRAD,0.0002); ARCRADVNAME=PAR_GDCORNERRAD; // Check if standalone call if (ulproginfo("",0,0)<=1 && bae_getactmenu()<0) { setarcmode(); exit(0); } // Get the currently active menu switch (bae_getactmenu()) { // Trace edit functions case MNU_GEDADDTRC : case MNU_GEDADDFTRC : case MNU_GEDTRCINSC : case MNU_GEDTRCMDC : dirsel=0; break; // Polygon edit functions case 500 : case 501 : case 502 : case 503 : case MNU_GEDADDDLINE : case 505 : case MNU_GEDPOLYINSC : case MNU_GEDPOLYMDC : case MNU_GEDGRPPOLY : case 5007 : case 5014 : dirsel=1; break; case MNU_GEDMOVEGRP : case MNU_GEDCOPYGRP : case MNU_GEDLOADGRP : bae_setanglelock(0); exit(0); // Ignore on default default : exit(0); } // Check if input data available ilay1=LAYERINV; if (ged_getinputdata(ix1,iy1,0.0,ilay1,0.0,0.0,0.0, ilay2,inpmode,0,ix3,iy3,ix2,iy2,it2,0.0,0.0,0.0,0.0,0)==0) { if (ilay2!=LAYERINV && dirsel==0) // Swap the edit direction ged_getinputdata( 0.0,0.0,0.0,ilay2,ix1,iy1,0.0,ilay1,inpmode,0, 0.0,0.0,0.0,0.0,0,ix3,iy3,ix2,iy2,it2); } else { exit(0); } if (bae_getgridlock() && gridx!=0.0 && gridy!=0.0) { // Snap to input grid bae_storemouseiact(3,px,py,0,LMB); bae_inpoint(px,py,px,py,0); } // Draw the arc drawarc(dirsel); } void drawarc(int dirsel) /* // Draw arc at current object // Parameters : // int dirsel : Direction selection mode */ { double sl1,sl2,slb /* Segment lengths */; double sx1,sx2 /* Segment X coordinates */; double sy1,sy2 /* Segment Y coordinates */; double wx,wy /* Bisector vector coordinates */; double wl /* Bisector length */; double smang /* Smaller segment angle */; double ang1 /* 1st segment angle */; double ang2 /* 2nd segment angle */; double ang /* Direction angle */; // Check if point placed at all if (ilay1==LAYERINV) { ix1=px; iy1=py; if (ARCMODE) { px+=ARCRADIUS; } else { if (bae_inpoint(ix1,iy1,px,py,3)!=0) exit(0); } bae_storemouseiact(1,px,py,2,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,dirsel ? 5 : (lay_menulaylinecnt()+12),LMB); bae_storemouseiact(1,ix1,iy1,2,LMB); bae_storemouseiact(1,2.0*ix1-px,2.0*iy1-py,2,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,dirsel ? 5 : (lay_menulaylinecnt()+12),LMB); bae_storemouseiact(1,ix1,iy1,2,LMB); bae_storemouseiact(1,px,py,2,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,0,LMB); exit(0); } // Check if only start point else if (it2==(-1)) { if (ARCMODE) { wx=px-ix1; wy=py-iy1; if (fabs(wx)<=SMALLVAL && fabs(wy)<=SMALLVAL) exit(0); wl=ARCRADIUS/sqrt(wx*wx+wy*wy); px=ix1+wx*wl; py=iy1+wy*wl; } bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,dirsel ? 5 : (lay_menulaylinecnt()+12),LMB); bae_storemouseiact(1,px,py,2,LMB); bae_storemouseiact(1,2.0*px-ix1,2.0*py-iy1,2,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,dirsel ? 5 : (lay_menulaylinecnt()+12),LMB); bae_storemouseiact(1,px,py,2,LMB); bae_storemouseiact(1,ix1,iy1,2,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,0,LMB); exit(0); } if (ARCMODE==2) { if (it2!=0) exit(0); // Get the normalized data of the first segment vector sx1=ix2-ix1; sy1=iy2-iy1; sl1=sqrt(sx1*sx1+sy1*sy1); // Skip zero length segments if (fabs(sl1)<=SMALLVAL) exit(0); sx1/=sl1; sy1/=sl1; // Get the normalized data of the second segment vector sx2=px-ix1; sy2=py-iy1; sl2=sqrt(sx2*sx2+sy2*sy2); // Skip zero length segments if (fabs(sl2)<=SMALLVAL) exit(0); sx2/=sl2; sy2/=sl2; // Get the normalized bisector vector wx=sx1+sx2; wy=sy1+sy2; wl=sqrt(wx*wx+wy*wy); // Skip same direction start/end segment if (wl==0.0) exit(0); wx/=wl; wy/=wl; // Get smaller angle between the two segments smang=acos(sx1*sx2+sy1*sy2)/2.0; // Check if nonzero angle if (fabs(smang)<=SMALLANG) exit(0); // Get the segment circle point distance slb=ARCRADIUS/tan(smang); // Get the bisector circle center distance wl=ARCRADIUS/sin(smang); // 1st segment shorter than required for rad ? if (slb>sl1) { // Adjust lengths wl*=sl1/slb; slb=sl1; } // 2nd segment shorter than required for rad ? if (slb>sl2) { // Adjust lengths wl*=sl2/slb; slb=sl2; } // Get real angle ang=fmod(atan2(sx2,sy2)-atan2(sx1,sy1)+2.0*PI,2.0*PI); // Dismiss edge point bae_storemouseiact(1,0.0,0.0,1,RMB); bae_storemenuiact(1,1,LMB); // Store arc points bae_storemouseiact(1,ix1+slb*sx1,iy1+slb*sy1,2,LMB); bae_storemouseiact(1,0.0,0.0,1,RMB); if (dirsel) bae_storemenuiact(1,ang>PI ? 6 : 5,LMB); else bae_storemenuiact(1, lay_menulaylinecnt()+(ang>PI ? 13 : 12),LMB); bae_storemouseiact(1,ix1+wl*wx,iy1+wl*wy,2,LMB); bae_storemouseiact(1,ix1+slb*sx2,iy1+slb*sy2,2,LMB); bae_storemouseiact(1,px,py,2,LMB); exit(0); } // Get segment angles wx=px-ix1; wy=py-iy1; if (fabs(wx)<=SMALLVAL && fabs(wy)<=SMALLVAL) exit(0); ang1=atan2(wy,wx); wx=ix1-ix2; wy=iy1-iy2; if (fabs(wx)<=SMALLVAL && fabs(wy)<=SMALLVAL) exit(0); // Check if arc if (it2==1) { // Rotate radius left wl=wx; wx=-wy; wy=wl; } else if (it2==2) { // Rotate radius right wl=wx; wx=wy; wy=-wl; } ang2=atan2(wy,wx); ang=ang1-ang2; while (ang>PI) ang-=2.0*PI; while (ang<-PI) ang+=2.0*PI; bae_storemouseiact(1,0.0,0.0,1,RMB); if (dirsel) bae_storemenuiact(1,ang>0.0 ? 5 : 6,LMB); else bae_storemenuiact(1, lay_menulaylinecnt()+(ang>0.0 ? 12 : 13),LMB); if (ARCMODE) { wl=ARCRADIUS/sqrt(wx*wx+wy*wy); wx*=wl; wy*=wl; if (ang>0.0) { bae_storemouseiact(1,ix1-wy,iy1+wx,2,LMB); bae_storemouseiact(1,ix1-wy+wx,iy1+wx+wy,2,LMB); } else { bae_storemouseiact(1,ix1+wy,iy1-wx,2,LMB); bae_storemouseiact(1,ix1+wy+wx,iy1-wx+wy,2,LMB); } } else { bae_storemouseiact(1,px,py,2,LMB); } } void setarcmode() /* // Set arc process mode */ { double pcol = 15.0 /* Parameter column */; double cy /* Dialog box current y coordinate */; int modidx = (-1) /* Arc mode dialog box item idx. */; int radidx = (-1) /* Radius dialog box item idx. */; int cunits /* Coordinate display units */; int repflag /* Repeat flag */; int res /* Result */; int varidx /* INI variable index */; // Check for dialog support if (bae_dialclr()) { // Set default selection bae_defmenusel(ARCMODE); // Select the arc mode bae_promptdialog(UPRAMODE); if ((ARCMODE=bae_askmenu(4, UPRMODE1,UPRMODE2,UPRMODE3,UPRABORT))<0 || ARCMODE>2) error_abort(); if (ARCMODE!=0) if (askdist(ARCRADIUS,lay_defusrunit() ? UPRARADI:UPRARADM,0) || ARCRADIUS==0.0) // Invalid input value error(ERRINPVAL); } else { // Store coordinate unit controls cunits= bae_getcoorddisp() ? 2 : 0; // Perform the dialog input loop repflag=1; do { bae_dialclr(); // Init. the y coordinate cy=DIAL_TOPMARG; // Store row offset mode controls modidx=dial_selboxpar(UPRMODE,ARCMODE,pcol,cy); dial_sbentry(3,0,UPRMODE1); dial_sbentry(3,1,UPRMODE2); dial_sbentry(3,2,UPRMODE3); if (ARCMODE!=0) { // Store radius controls radidx= dial_distpar(UPRARADD,5,ARCRADIUS,pcol,cy); dial_label(0.0,cy,UPRDUNIT); bae_dialaddcontrol(PA_RBF,0,1,cunits,0.0,0.0, 0.0,"",0,DIAL_LEFTMARG+pcol,cy,0.0,UPRDUNITMM); bae_dialaddcontrol(PA_RBN,2,2,0,0.0,0.0,0.0,"", 0,DIAL_LEFTMARG+pcol+6.0,cy,0.0,UPRDUNITMIL); cy+=DIAL_CTRVSTEP; } else { radidx=(-1); } cy+=DIAL_BUTVSTEP-DIAL_CTRVSTEP; if (callertype==ULIPGED) { dial_hsep(cy); cy-=DIAL_SEPVSTEP; bae_dialaddcontrol(PA_VSEP|PA_VBRDREL,0,0,0, 0.0,0.0,0.0,"",0,DIAL_LEFTMARG+COL2-2.0,cy, DIAL_BOTSMARG,""); cy+=DIAL_SEPVSTEP; dial_label(0.0,cy,UPRTYPTRACE); dial_label(COL2,cy,UPRTYPPOLY); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,4,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN1); bae_dialaddcontrol(PA_ACT,0,16,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN1); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,5,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN2); bae_dialaddcontrol(PA_ACT,0,17,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN2); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,6,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN3); bae_dialaddcontrol(PA_ACT,0,18,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN3); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,7,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN4); bae_dialaddcontrol(PA_ACT,0,19,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN4); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,8,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN5); bae_dialaddcontrol(PA_ACT,0,20,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN5); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,9,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN6); bae_dialaddcontrol(PA_ACT,0,21,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN6); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,10,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN7); bae_dialaddcontrol(PA_ACT,0,22,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN7); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,11,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN8); bae_dialaddcontrol(PA_ACT,0,23,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN8); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,12,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN9); bae_dialaddcontrol(PA_ACT,0,24,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN9); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,13,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN10); bae_dialaddcontrol(PA_ACT,0,25,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN10); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,14,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN11); bae_dialaddcontrol(PA_ACT,0,26,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN11); cy+=DIAL_BUTVSTEP; bae_dialaddcontrol(PA_ACT,0,15,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG,cy,BUTWIDTH,UPRCORN12); bae_dialaddcontrol(PA_ACT,0,27,0,0.0,0.0,0.0, "",0,DIAL_LEFTMARG+COL2,cy,BUTWIDTH,UPRCORN12); cy+=DIAL_BUTVSTEP; } dial_hsep(cy); dial_okabortini(cy,49.0+DIAL_RIGHTSMARG,28); // Call the dialog function bae_setintpar(16,5000); res=bae_dialaskparams(UPRARCPARAM,cunits, DIAL_LEFTMARG+pcol+34.0+DIAL_RIGHTSMARG,cy); bae_dialgetdata(modidx,ARCMODE,0.0,""); if (radidx!=(-1)) bae_dialgetdata(radidx,0,ARCRADIUS,""); switch (res) { case 0 : repflag=0; break; // Switch to mm units case 1 : cunits=0; break; // Switch to mil units case 2 : cunits=2; break; // Arc mode change case 3 : break; // Arc parameter store case 28 : varidx=0; bae_iniintset(varidx,PAR_ARCDRAW,ARCMODE); bae_inidimset(varidx,ARCRADVNAME,ARCRADIUS); bae_iniwrite(varidx); break; // Fail/abort case (-1) : default : if (res>=4 && res<=15) { // Store the new arc mode varset(PAR_ARCDRAW,ARCMODE); varset(VAR_CORNERR,ARCRADIUS); bae_clriactqueue(); bae_storemenuiact(1,res-4,LMB); ulsystem(UL_TRACERND,0); exit(0); } else if (res>=16 && res<=27) { // Store the new arc mode varset(PAR_ARCDRAW,ARCMODE); varset(VAR_CORNERR,ARCRADIUS); bae_clriactqueue(); bae_storemenuiact(1,res-16,LMB); ulsystem(UL_POLYRND,0); exit(0); } error_abort(); } // Stop if no further repeat requests } while (repflag); } // Store the new arc mode to global variable varset(PAR_ARCDRAW,ARCMODE); varset(VAR_CORNERR,ARCRADIUS); exit(0); } // User Language program end