2275 lines
50 KiB
C++
2275 lines
50 KiB
C++
// hdrawDoc.cpp : implementation of the ChdrawDoc class (continued...)
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "femm.h"
|
|
#include "hdrawDoc.h"
|
|
#include "hdrawView.h"
|
|
#include "hd_probdlg.h"
|
|
#include "hd_PtProp.h"
|
|
#include "hd_OpBlkDlg.h"
|
|
#include "hd_OpNodeDlg.h"
|
|
#include "hd_OpSegDlg.h"
|
|
#include "hd_OpArcSegDlg.h"
|
|
#include "ArcDlg.h"
|
|
#include "DXFImport.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
extern BOOL bLinehook;
|
|
//-----------------------------------------------------------------
|
|
|
|
BOOL ChdrawDoc::ReadDXF(CString fname,double DefTol)
|
|
{
|
|
FILE *fp;
|
|
int j,k;
|
|
CArray<CString,CString&> layerlist;
|
|
CString myLayer;
|
|
|
|
if( (fp=fopen(fname,"rt"))==NULL ) return FALSE;
|
|
NoDraw=TRUE;
|
|
|
|
// clear out any old drawing that we might have;
|
|
// nodelist.RemoveAll();
|
|
// linelist.RemoveAll();
|
|
// arclist.RemoveAll();
|
|
// blocklist.RemoveAll();
|
|
// undonodelist.RemoveAll();
|
|
// undolinelist.RemoveAll();
|
|
// undoarclist.RemoveAll();
|
|
// undoblocklist.RemoveAll();
|
|
// nodeproplist.RemoveAll();
|
|
// lineproplist.RemoveAll();
|
|
// blockproplist.RemoveAll();
|
|
// circproplist.RemoveAll();
|
|
// meshnode.RemoveAll();
|
|
// meshline.RemoveAll();
|
|
// greymeshline.RemoveAll();
|
|
|
|
char s[256];
|
|
char v[256];
|
|
BOOL PolylineFlag=FALSE;
|
|
CNode n[4];
|
|
CSegment segm;
|
|
CArcSegment asegm;
|
|
CComplex c,p,q;
|
|
double R,a0,a1;
|
|
int xx,PolyLineClosed,firstpoint;
|
|
double angle=0;
|
|
|
|
while (fgets(s,256,fp)!=NULL)
|
|
{
|
|
if (strncmp(s,"LAYER",5)==0)
|
|
{
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==2){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
layerlist.Add(myLayer);
|
|
}
|
|
} while(1>0);
|
|
}
|
|
|
|
if (strncmp(s,"POINT",5)==0)
|
|
{
|
|
xx=0;
|
|
n[0].InGroup=0;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==10) { n[0].x=atof(v); xx=xx | 1; }
|
|
if (k==20) { n[0].y=atof(v); xx=xx | 2; }
|
|
if (k==8){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
for(j=0;j<layerlist.GetSize();j++)
|
|
if (myLayer==layerlist[j]) n[0].InGroup=j;
|
|
}
|
|
} while(1>0);
|
|
if (xx==3) nodelist.Add(n[0]);
|
|
}
|
|
|
|
if (strncmp(s,"LWPOLYLINE",10)==0)
|
|
{
|
|
int segs=0;
|
|
PolyLineClosed=FALSE;
|
|
firstpoint=-1;
|
|
angle = 0;
|
|
n[0].InGroup=0;
|
|
segm.InGroup=0;
|
|
asegm.InGroup=0;
|
|
int n0,n1;
|
|
xx=0;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==8){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
for(j=0;j<layerlist.GetSize();j++)
|
|
if (myLayer==layerlist[j]){
|
|
n[0].InGroup=j;
|
|
segm.InGroup=j;
|
|
asegm.InGroup=j;
|
|
}
|
|
}
|
|
if (k==10) { n[0].x=atof(v); xx=xx | 1; }
|
|
if (k==20) { n[0].y=atof(v); xx=xx | 2; }
|
|
if (k==42) {
|
|
angle=720.*atan(atof(v))/PI;
|
|
if(angle<-360.) angle=-360.;
|
|
if(angle>360.) angle=360.;
|
|
}
|
|
if (k==70) PolyLineClosed=TRUE;
|
|
if (xx==3){
|
|
j=(int) nodelist.GetSize();
|
|
nodelist.Add(n[0]);
|
|
xx=0;
|
|
if(segs==0) firstpoint=j;
|
|
else{
|
|
if(angle==0)
|
|
{
|
|
segm.n0=j;
|
|
segm.n1=j-1;
|
|
linelist.Add(segm);
|
|
}
|
|
else{
|
|
if(angle>0) { n0=j-1; n1=j; }
|
|
else{ n0=j; n1=j-1; angle=fabs(angle); }
|
|
if(angle>180.)
|
|
{
|
|
CComplex p0,p1,p2;
|
|
angle/=2.;
|
|
p0=nodelist[n0].x + I*nodelist[n0].y;
|
|
p1=nodelist[n1].x + I*nodelist[n1].y;
|
|
p2=(p0+p1)/2. - I*(1.-cos(angle*PI/180.))*(p1-p0)/
|
|
(2.*sin(angle*PI/180.));
|
|
n[0].x=Re(p2);
|
|
n[0].y=Im(p2);
|
|
nodelist.InsertAt(j,n[0]);
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
if (n0<n1){
|
|
asegm.n0=n0;
|
|
asegm.n1=j;
|
|
}
|
|
else{
|
|
asegm.n0=j;
|
|
asegm.n1=n1;
|
|
}
|
|
arclist.Add(asegm);
|
|
if(n1==j){
|
|
n1++;
|
|
n0=j;
|
|
}
|
|
else{
|
|
n0++;
|
|
n1=j;
|
|
}
|
|
}
|
|
asegm.n0=n0;
|
|
asegm.n1=n1;
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
arclist.Add(asegm);
|
|
angle=0;
|
|
}
|
|
}
|
|
segs++;
|
|
}
|
|
} while(1>0);
|
|
if ((PolyLineClosed==TRUE) && (firstpoint>=0) && (segs>0))
|
|
{
|
|
// take care of closing the contour, if required.
|
|
j=(int) nodelist.GetSize()-1;
|
|
if(angle==0)
|
|
{
|
|
segm.n0=j;
|
|
segm.n1=firstpoint;
|
|
linelist.Add(segm);
|
|
}
|
|
else{
|
|
if(angle>0) { n0=j; n1=firstpoint; }
|
|
else{ n0=firstpoint; n1=j; angle=fabs(angle); }
|
|
if(angle>180.)
|
|
{
|
|
CComplex p0,p1,p2;
|
|
angle/=2.;
|
|
p0=nodelist[n0].x + I*nodelist[n0].y;
|
|
p1=nodelist[n1].x + I*nodelist[n1].y;
|
|
p2=(p0+p1)/2. - I*(1.-cos(angle*PI/180.))*(p1-p0)/
|
|
(2.*sin(angle*PI/180.));
|
|
n[0].x=Re(p2);
|
|
n[0].y=Im(p2);
|
|
nodelist.Add(n[0]);
|
|
j++;
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
if (n0>n1){
|
|
asegm.n0=n0;
|
|
asegm.n1=j;
|
|
}
|
|
else{
|
|
asegm.n0=j;
|
|
asegm.n1=n1;
|
|
}
|
|
arclist.Add(asegm);
|
|
|
|
if(n1==j-1) n1=j;
|
|
else n0=j;
|
|
|
|
}
|
|
asegm.n0=n0;
|
|
asegm.n1=n1;
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
arclist.Add(asegm);
|
|
angle=0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (strncmp(s,"POLYLINE",8)==0)
|
|
{
|
|
PolylineFlag=-1;
|
|
firstpoint=-1;
|
|
PolyLineClosed=FALSE;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==70) {
|
|
j=atoi(v);
|
|
if (j==1) PolyLineClosed=TRUE;
|
|
}
|
|
} while(1>0);
|
|
|
|
}
|
|
|
|
if (strncmp(s,"SEQEND",6)==0)
|
|
{
|
|
PolylineFlag=FALSE;
|
|
int j = ((int) nodelist.GetSize())-1;
|
|
if ((PolyLineClosed==TRUE) && (firstpoint>=0))
|
|
{
|
|
if (angle == 0.0)
|
|
{
|
|
segm.n0=j;
|
|
segm.n1=firstpoint;
|
|
linelist.Add(segm);
|
|
}
|
|
else
|
|
{
|
|
int n0, n1;
|
|
if(angle>0) { n0=j; n1=firstpoint; }
|
|
else{ n0=firstpoint; n1=j; angle=fabs(angle); }
|
|
if(angle>180.)
|
|
{
|
|
CComplex p0,p1,p2;
|
|
angle/=2.;
|
|
p0=nodelist[n0].x + I*nodelist[n0].y;
|
|
p1=nodelist[n1].x + I*nodelist[n1].y;
|
|
p2=(p0+p1)/2. - I*(1.-cos(angle*PI/180.))*(p1-p0)/
|
|
(2.*sin(angle*PI/180.));
|
|
n[0].x=Re(p2);
|
|
n[0].y=Im(p2);
|
|
nodelist.Add(n[0]);
|
|
j++;
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
if (n0>n1){
|
|
asegm.n0=n0;
|
|
asegm.n1=j;
|
|
}
|
|
else{
|
|
asegm.n0=j;
|
|
asegm.n1=n1;
|
|
}
|
|
arclist.Add(asegm);
|
|
|
|
if(n1==j-1) n1=j;
|
|
else n0=j;
|
|
|
|
}
|
|
asegm.n0=n0;
|
|
asegm.n1=n1;
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
PolyLineClosed=FALSE;
|
|
angle = 0.0;
|
|
}
|
|
|
|
if (strncmp(s,"VERTEX",6)==0)
|
|
{
|
|
n[0].InGroup=0;
|
|
segm.InGroup=0;
|
|
asegm.InGroup=0;
|
|
double next_angle = 0.0;
|
|
xx=0;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==8){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
for(j=0;j<layerlist.GetSize();j++)
|
|
if (myLayer==layerlist[j]){
|
|
n[0].InGroup=j;
|
|
segm.InGroup=j;
|
|
asegm.InGroup=j;
|
|
}
|
|
}
|
|
if (k==10) { n[0].x=atof(v); xx |= 1 << 0; }
|
|
if (k==20) { n[0].y=atof(v); xx |= 1 << 1; }
|
|
if (k==42) {
|
|
// Bulge argument for arc segments within a POLYLINE
|
|
// The bulge applies to the line connecting this VERTEX and the *next* one.
|
|
next_angle=720.0*atan(atof(v))/PI;
|
|
if(next_angle<-360.) next_angle=-360.;
|
|
if(next_angle>360.) next_angle=360.;
|
|
}
|
|
} while(1>0);
|
|
|
|
if(xx==3)
|
|
{
|
|
nodelist.Add(n[0]);
|
|
if (angle != 0.0)
|
|
{
|
|
j = (int)nodelist.GetSize();
|
|
|
|
int n0, n1;
|
|
if(angle>0) { n0=j-2; n1=j-1; }
|
|
else{ n0=j-1; n1=j-2; angle=fabs(angle); }
|
|
|
|
if(angle>180.)
|
|
{
|
|
CComplex p0,p1,p2;
|
|
angle/=2.;
|
|
p0=nodelist[n0].x + I*nodelist[n0].y;
|
|
p1=nodelist[n1].x + I*nodelist[n1].y;
|
|
p2=(p0+p1)/2. - I*(1.-cos(angle*PI/180.))*(p1-p0)/
|
|
(2.*sin(angle*PI/180.));
|
|
n[0].x=Re(p2);
|
|
n[0].y=Im(p2);
|
|
nodelist.InsertAt(j,n[0]);
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
if (n0<n1){
|
|
asegm.n0=n0;
|
|
asegm.n1=j;
|
|
}
|
|
else{
|
|
asegm.n0=j;
|
|
asegm.n1=n1;
|
|
}
|
|
arclist.Add(asegm);
|
|
if(n1==j){
|
|
n1++;
|
|
n0=j;
|
|
}
|
|
else{
|
|
n0++;
|
|
n1=j;
|
|
}
|
|
}
|
|
asegm.n0=n0;
|
|
asegm.n1=n1;
|
|
asegm.ArcLength=angle;
|
|
asegm.MaxSideLength=5.;
|
|
arclist.Add(asegm);
|
|
}
|
|
else
|
|
{
|
|
if (PolylineFlag==TRUE){
|
|
j=(int) nodelist.GetSize();
|
|
segm.n0=j-2; segm.n1=j-1;
|
|
linelist.Add(segm);
|
|
}
|
|
if (PolylineFlag==-1){
|
|
firstpoint=((int) nodelist.GetSize())-1;
|
|
PolylineFlag=TRUE;
|
|
}
|
|
}
|
|
}
|
|
angle = next_angle;
|
|
}
|
|
|
|
if (strncmp(s,"LINE",4)==0)
|
|
{
|
|
n[0].InGroup=0;
|
|
n[1].InGroup=0;
|
|
segm.InGroup=0;
|
|
xx=0;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==8){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
for(j=0;j<layerlist.GetSize();j++)
|
|
if (myLayer==layerlist[j]){
|
|
n[0].InGroup=j;
|
|
n[1].InGroup=j;
|
|
segm.InGroup=j;
|
|
}
|
|
}
|
|
if (k==10) { n[0].x=atof(v); xx=xx | 1; }
|
|
if (k==20) { n[0].y=atof(v); xx=xx | 2; }
|
|
if (k==11) { n[1].x=atof(v); xx=xx | 4; }
|
|
if (k==21) { n[1].y=atof(v); xx=xx | 8; }
|
|
} while(1>0);
|
|
|
|
if (xx==15)
|
|
{
|
|
j=(int) nodelist.GetSize();
|
|
nodelist.Add(n[0]);
|
|
nodelist.Add(n[1]);
|
|
segm.n0=j; segm.n1=j+1;
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
|
|
// catch ARCALIGNEDTEXT, which derails the ARC code...
|
|
if (strncmp(s,"ARCA",4)==0) s[0]=NULL;
|
|
|
|
if (strncmp(s,"ARC",3)==0)
|
|
{
|
|
n[0].InGroup=0;
|
|
n[1].InGroup=0;
|
|
asegm.InGroup=0;
|
|
xx=0;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==8){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
for(j=0;j<layerlist.GetSize();j++)
|
|
if (myLayer==layerlist[j]){
|
|
n[0].InGroup=j;
|
|
n[1].InGroup=j;
|
|
asegm.InGroup=j;
|
|
}
|
|
}
|
|
if (k==10) { c.re=atof(v); xx=xx | 1; }
|
|
if (k==20) { c.im=atof(v); xx=xx | 2; }
|
|
if (k==40) { R=atof(v); xx=xx | 4; }
|
|
if (k==50) { a0=atof(v); xx=xx | 8; }
|
|
if (k==51) { a1=atof(v); xx=xx | 16; }
|
|
} while(1>0);
|
|
|
|
if(xx==31)
|
|
{
|
|
if (a1<a0) a1+=360.;
|
|
|
|
if ((a1-a0)<=180.){
|
|
p=R*exp(I*PI*a0/180.) + c;
|
|
q=R*exp(I*PI*a1/180.) + c;
|
|
n[0].x=p.re; n[1].x=q.re;
|
|
n[0].y=p.im; n[1].y=q.im;
|
|
j=(int) nodelist.GetSize();
|
|
nodelist.Add(n[0]);
|
|
nodelist.Add(n[1]);
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.MaxSideLength=5.;
|
|
asegm.ArcLength=(a1-a0);
|
|
arclist.Add(asegm);
|
|
}
|
|
else{
|
|
p=R*exp(I*PI*a0/180.) + c;
|
|
q=R*exp(I*PI*(a1+a0)/360.) + c;
|
|
n[0].x=p.re; n[1].x=q.re;
|
|
n[0].y=p.im; n[1].y=q.im;
|
|
j=(int) nodelist.GetSize();
|
|
nodelist.Add(n[0]);
|
|
nodelist.Add(n[1]);
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.MaxSideLength=5.;
|
|
asegm.ArcLength=(a1-a0)/2.;
|
|
arclist.Add(asegm);
|
|
|
|
p=q;
|
|
q=R*exp(I*PI*a1/180.) + c;
|
|
n[0].x=p.re; n[1].x=q.re;
|
|
n[0].y=p.im; n[1].y=q.im;
|
|
j=(int) nodelist.GetSize();
|
|
nodelist.Add(n[0]);
|
|
nodelist.Add(n[1]);
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.MaxSideLength=5.;
|
|
asegm.ArcLength=(a1-a0)/2.;
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (strncmp(s,"CIRCLE",6)==0)
|
|
{
|
|
n[0].InGroup=0;
|
|
n[0].InGroup=0;
|
|
asegm.InGroup=0;
|
|
xx=0;
|
|
do{
|
|
if (fgets(s,256,fp)==NULL) break;
|
|
k=atoi(s);
|
|
if (k==0) break;
|
|
fgets(v,256,fp);
|
|
if (k==8){
|
|
sscanf(v,"%s",s);
|
|
myLayer=s;
|
|
for(j=0;j<layerlist.GetSize();j++)
|
|
if (myLayer==layerlist[j]){
|
|
n[0].InGroup=j;
|
|
n[1].InGroup=j;
|
|
asegm.InGroup=j;
|
|
}
|
|
}
|
|
if (k==10) { c.re=atof(v); xx=xx | 1; }
|
|
if (k==20) { c.im=atof(v); xx=xx | 2; }
|
|
if (k==40) { R=atof(v); xx=xx | 4; }
|
|
} while(1>0);
|
|
|
|
if(xx==7)
|
|
{
|
|
n[0].x=c.re+R; n[1].x=c.re-R;
|
|
n[0].y=c.im; n[1].y=c.im;
|
|
j=(int) nodelist.GetSize();
|
|
nodelist.Add(n[0]);
|
|
nodelist.Add(n[1]);
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.MaxSideLength=5.;
|
|
asegm.ArcLength=180.;
|
|
arclist.Add(asegm);
|
|
asegm.n1=j; asegm.n0=j+1;
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
// could be that nothing actually got read. We want to
|
|
// catch this case and tell the user about it.
|
|
if(nodelist.GetSize()==0) return FALSE;
|
|
|
|
// suggest the proper tolerance
|
|
CComplex p0,p1;
|
|
CDXFImport dlg;
|
|
int i;
|
|
|
|
p0=nodelist[0].CC();
|
|
p1=p0;
|
|
for(i=1;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].x<p0.re) p0.re=nodelist[i].x;
|
|
if(nodelist[i].x>p1.re) p1.re=nodelist[i].x;
|
|
if(nodelist[i].y<p0.im) p0.im=nodelist[i].y;
|
|
if(nodelist[i].y>p1.im) p1.im=nodelist[i].y;
|
|
}
|
|
|
|
R=abs(p1-p0)*1.e-04;
|
|
dlg.m_dxftol=floor(R/pow(10.,floor(log10(R))))*pow(10.,floor(log10(R)));
|
|
|
|
if(DefTol<0)
|
|
{
|
|
dlg.DoModal();
|
|
FancyEnforcePSLG(dlg.m_dxftol);
|
|
}
|
|
else
|
|
{
|
|
if (DefTol==0) DefTol=dlg.m_dxftol;
|
|
FancyEnforcePSLG(DefTol);
|
|
}
|
|
|
|
NoDraw=FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void ChdrawDoc::RotateMove(CComplex c, double t, int EditAction)
|
|
{
|
|
int i;
|
|
CComplex x,z;
|
|
|
|
z=exp(I*t*PI/180);
|
|
|
|
if(EditAction==0)
|
|
{
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
x.Set(nodelist[i].x,nodelist[i].y);
|
|
x=(x-c)*z+c;
|
|
nodelist[i].x=x.re;
|
|
nodelist[i].y=x.im;
|
|
}
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
if(EditAction==1)
|
|
{
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
nodelist[linelist[i].n0].IsSelected=TRUE;
|
|
nodelist[linelist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
RotateMove(c,t,0);
|
|
return;
|
|
}
|
|
|
|
if(EditAction==2)
|
|
{
|
|
for(i=0;i<blocklist.GetSize();i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
x.Set(blocklist[i].x,blocklist[i].y);
|
|
x=(x-c)*z+c;
|
|
blocklist[i].x=x.re;
|
|
blocklist[i].y=x.im;
|
|
}
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
if(EditAction==3)
|
|
{
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
nodelist[arclist[i].n0].IsSelected=TRUE;
|
|
nodelist[arclist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
RotateMove(c,t,0);
|
|
return;
|
|
}
|
|
|
|
if(EditAction==4)
|
|
{
|
|
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
nodelist[linelist[i].n0].IsSelected=TRUE;
|
|
nodelist[linelist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
nodelist[arclist[i].n0].IsSelected=TRUE;
|
|
nodelist[arclist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
x.Set(nodelist[i].x,nodelist[i].y);
|
|
x=(x-c)*z+c;
|
|
nodelist[i].x=x.re;
|
|
nodelist[i].y=x.im;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<blocklist.GetSize();i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
x.Set(blocklist[i].x,blocklist[i].y);
|
|
x=(x-c)*z+c;
|
|
blocklist[i].x=x.re;
|
|
blocklist[i].y=x.im;
|
|
}
|
|
}
|
|
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ChdrawDoc::TranslateMove(double dx, double dy, int EditAction)
|
|
{
|
|
int i;
|
|
|
|
if(EditAction==0)
|
|
{
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
nodelist[i].x+=dx;
|
|
nodelist[i].y+=dy;
|
|
}
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
if(EditAction==1)
|
|
{
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
nodelist[linelist[i].n0].IsSelected=TRUE;
|
|
nodelist[linelist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
TranslateMove(dx,dy,0);
|
|
return;
|
|
}
|
|
|
|
if(EditAction==2)
|
|
{
|
|
for(i=0;i<blocklist.GetSize();i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
blocklist[i].x+=dx;
|
|
blocklist[i].y+=dy;
|
|
}
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
if(EditAction==3)
|
|
{
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
nodelist[arclist[i].n0].IsSelected=TRUE;
|
|
nodelist[arclist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
TranslateMove(dx,dy,0);
|
|
return;
|
|
}
|
|
|
|
if(EditAction==4)
|
|
{
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
nodelist[linelist[i].n0].IsSelected=TRUE;
|
|
nodelist[linelist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
nodelist[arclist[i].n0].IsSelected=TRUE;
|
|
nodelist[arclist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
nodelist[i].x+=dx;
|
|
nodelist[i].y+=dy;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<blocklist.GetSize();i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
blocklist[i].x+=dx;
|
|
blocklist[i].y+=dy;
|
|
}
|
|
}
|
|
|
|
EnforcePSLG();
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void ChdrawDoc::RotateCopy(CComplex c, double dt, int ncopies, int EditAction)
|
|
{
|
|
int i,j,k,nc;
|
|
CComplex x,z;
|
|
double t;
|
|
|
|
for(nc=0;nc<ncopies;nc++){
|
|
t=((double) (nc+1))*dt;
|
|
|
|
z=exp(I*t*PI/180);
|
|
|
|
if(EditAction==0)
|
|
{
|
|
CNode node;
|
|
k=(int) nodelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
x.Set(nodelist[i].x,nodelist[i].y);
|
|
node=nodelist[i];
|
|
x=(x-c)*z+c;
|
|
node.x=x.re;
|
|
node.y=x.im;
|
|
node.IsSelected=FALSE;
|
|
nodelist.Add(node);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==1)
|
|
{
|
|
CSegment segm;
|
|
CNode n0,n1;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
n0=nodelist[linelist[i].n0];
|
|
n1=nodelist[linelist[i].n1];
|
|
|
|
x.Set(n0.x,n0.y);
|
|
x=(x-c)*z+c;
|
|
n0.x=x.re;
|
|
n0.y=x.im;
|
|
|
|
x.Set(n1.x,n1.y);
|
|
x=(x-c)*z+c;
|
|
n1.x=x.re;
|
|
n1.y=x.im;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
segm=linelist[i];
|
|
segm.n0=j; segm.n1=j+1;
|
|
segm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==2)
|
|
{
|
|
CBlockLabel lbl;
|
|
k=(int) blocklist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
x.Set(blocklist[i].x,blocklist[i].y);
|
|
lbl=blocklist[i];
|
|
x=(x-c)*z+c;
|
|
lbl.x=x.re;
|
|
lbl.y=x.im;
|
|
lbl.IsSelected=FALSE;
|
|
|
|
blocklist.Add(lbl);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==3)
|
|
{
|
|
CArcSegment asegm;
|
|
CNode n0,n1;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
n0=nodelist[arclist[i].n0];
|
|
n1=nodelist[arclist[i].n1];
|
|
|
|
x.Set(n0.x,n0.y);
|
|
x=(x-c)*z+c;
|
|
n0.x=x.re;
|
|
n0.y=x.im;
|
|
|
|
x.Set(n1.x,n1.y);
|
|
x=(x-c)*z+c;
|
|
n1.x=x.re;
|
|
n1.y=x.im;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
asegm=arclist[i];
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==4){
|
|
|
|
// copy selected nodes;
|
|
CNode node;
|
|
k=(int) nodelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
x.Set(nodelist[i].x,nodelist[i].y);
|
|
node=nodelist[i];
|
|
x=(x-c)*z+c;
|
|
node.x=x.re;
|
|
node.y=x.im;
|
|
node.IsSelected=FALSE;
|
|
nodelist.Add(node);
|
|
}
|
|
}
|
|
|
|
// copy selected segments;
|
|
CSegment segm;
|
|
CNode n0,n1;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
n0=nodelist[linelist[i].n0];
|
|
n1=nodelist[linelist[i].n1];
|
|
|
|
x.Set(n0.x,n0.y);
|
|
x=(x-c)*z+c;
|
|
n0.x=x.re;
|
|
n0.y=x.im;
|
|
n0.IsSelected=0;
|
|
|
|
x.Set(n1.x,n1.y);
|
|
x=(x-c)*z+c;
|
|
n1.x=x.re;
|
|
n1.y=x.im;
|
|
n1.IsSelected=0;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
segm=linelist[i];
|
|
segm.n0=j; segm.n1=j+1;
|
|
segm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
|
|
// copy selected arc segments
|
|
CArcSegment asegm;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
n0=nodelist[arclist[i].n0];
|
|
n1=nodelist[arclist[i].n1];
|
|
|
|
x.Set(n0.x,n0.y);
|
|
x=(x-c)*z+c;
|
|
n0.x=x.re;
|
|
n0.y=x.im;
|
|
n0.IsSelected=0;
|
|
|
|
x.Set(n1.x,n1.y);
|
|
x=(x-c)*z+c;
|
|
n1.x=x.re;
|
|
n1.y=x.im;
|
|
n1.IsSelected=0;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
asegm=arclist[i];
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
|
|
// copy selected block labels
|
|
CBlockLabel lbl;
|
|
k=(int) blocklist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
x.Set(blocklist[i].x,blocklist[i].y);
|
|
lbl=blocklist[i];
|
|
x=(x-c)*z+c;
|
|
lbl.x=x.re;
|
|
lbl.y=x.im;
|
|
lbl.IsSelected=FALSE;
|
|
|
|
blocklist.Add(lbl);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
EnforcePSLG();
|
|
return;
|
|
|
|
}
|
|
|
|
void ChdrawDoc::TranslateCopy(double incx, double incy, int ncopies, int EditAction)
|
|
{
|
|
int i,j,k,nc;
|
|
double dx,dy;
|
|
for(nc=0;nc<ncopies;nc++){
|
|
dx=((double)(nc+1))*incx;
|
|
dy=((double)(nc+1))*incy;
|
|
|
|
if(EditAction==0)
|
|
{
|
|
CNode node;
|
|
k=(int) nodelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
node=nodelist[i];
|
|
node.x+=dx;
|
|
node.y+=dy;
|
|
node.IsSelected=FALSE;
|
|
nodelist.Add(node);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==1)
|
|
{
|
|
CSegment segm;
|
|
CNode n0,n1;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
n0=nodelist[linelist[i].n0];
|
|
n1=nodelist[linelist[i].n1];
|
|
|
|
n0.x+=dx;
|
|
n0.y+=dy;
|
|
|
|
n1.x+=dx;
|
|
n1.y+=dy;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
segm=linelist[i];
|
|
segm.n0=j; segm.n1=j+1;
|
|
segm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==2)
|
|
{
|
|
CBlockLabel lbl;
|
|
k=(int) blocklist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
lbl=blocklist[i];
|
|
lbl.x+=dx;
|
|
lbl.y+=dy;
|
|
lbl.IsSelected=FALSE;
|
|
blocklist.Add(lbl);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==3)
|
|
{
|
|
CArcSegment asegm;
|
|
CNode n0,n1;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
n0=nodelist[arclist[i].n0];
|
|
n1=nodelist[arclist[i].n1];
|
|
|
|
n0.x+=dx;
|
|
n0.y+=dy;
|
|
n0.IsSelected=FALSE;
|
|
|
|
n1.x+=dx;
|
|
n1.y+=dy;
|
|
n1.IsSelected=FALSE;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
asegm=arclist[i];
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(EditAction==4)
|
|
{
|
|
CNode node;
|
|
k=(int) nodelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
node=nodelist[i];
|
|
node.x+=dx;
|
|
node.y+=dy;
|
|
node.IsSelected=FALSE;
|
|
nodelist.Add(node);
|
|
}
|
|
}
|
|
|
|
CSegment segm;
|
|
CNode n0,n1;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
n0=nodelist[linelist[i].n0];
|
|
n1=nodelist[linelist[i].n1];
|
|
|
|
n0.x+=dx;
|
|
n0.y+=dy;
|
|
n0.IsSelected=FALSE;
|
|
|
|
n1.x+=dx;
|
|
n1.y+=dy;
|
|
n1.IsSelected=FALSE;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
segm=linelist[i];
|
|
segm.n0=j; segm.n1=j+1;
|
|
segm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
|
|
CBlockLabel lbl;
|
|
k=(int) blocklist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
lbl=blocklist[i];
|
|
lbl.x+=dx;
|
|
lbl.y+=dy;
|
|
lbl.IsSelected=FALSE;
|
|
blocklist.Add(lbl);
|
|
}
|
|
}
|
|
|
|
CArcSegment asegm;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
n0=nodelist[arclist[i].n0];
|
|
n1=nodelist[arclist[i].n1];
|
|
|
|
n0.x+=dx;
|
|
n0.y+=dy;
|
|
n0.IsSelected=FALSE;
|
|
|
|
n1.x+=dx;
|
|
n1.y+=dy;
|
|
n1.IsSelected=FALSE;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
asegm=arclist[i];
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
void ChdrawDoc::EnforcePSLG()
|
|
{
|
|
EnforcePSLG(0);
|
|
}
|
|
|
|
void ChdrawDoc::EnforcePSLG(double tol)
|
|
{
|
|
/* need to enforce:
|
|
1) no duplicate point;
|
|
2) no intersections between line segments, lines and arcs, or arcs;
|
|
3) no duplicate block labels;
|
|
4) no overlapping lines or arcs.
|
|
|
|
can do this by cleaning out the various lists, and rebuilding them
|
|
using the ``add'' functions that ensure that things come out right.
|
|
*/
|
|
|
|
CArray< CNode, CNode&> newnodelist;
|
|
CArray< CSegment, CSegment&> newlinelist;
|
|
CArray< CArcSegment, CArcSegment&> newarclist;
|
|
CArray< CBlockLabel, CBlockLabel&> newblocklist;
|
|
int i;
|
|
CComplex p0,p1;
|
|
double d;
|
|
|
|
newnodelist.RemoveAll();
|
|
newlinelist.RemoveAll();
|
|
newarclist.RemoveAll();
|
|
newblocklist.RemoveAll();
|
|
|
|
for(i=0;i<nodelist.GetSize();i++) newnodelist.Add(nodelist[i]);
|
|
for(i=0;i<linelist.GetSize();i++) newlinelist.Add(linelist[i]);
|
|
for(i=0;i<arclist.GetSize();i++) newarclist.Add(arclist[i]);
|
|
for(i=0;i<blocklist.GetSize();i++) newblocklist.Add(blocklist[i]);
|
|
|
|
nodelist.RemoveAll();
|
|
linelist.RemoveAll();
|
|
arclist.RemoveAll();
|
|
blocklist.RemoveAll();
|
|
|
|
// find out what tolerance is so that there are not nodes right on
|
|
// top of each other;
|
|
if(tol==0){
|
|
if (newnodelist.GetSize()<2) d=1.e-08;
|
|
else{
|
|
p0=newnodelist[0].CC();
|
|
p1=p0;
|
|
for(i=1;i<newnodelist.GetSize();i++)
|
|
{
|
|
if(newnodelist[i].x<p0.re) p0.re=newnodelist[i].x;
|
|
if(newnodelist[i].x>p1.re) p1.re=newnodelist[i].x;
|
|
if(newnodelist[i].y<p0.im) p0.im=newnodelist[i].y;
|
|
if(newnodelist[i].y>p1.im) p1.im=newnodelist[i].y;
|
|
}
|
|
d=abs(p1-p0)*CLOSE_ENOUGH;
|
|
}
|
|
}
|
|
else d=tol;
|
|
|
|
// put in all of the nodes;
|
|
for(i=0;i<newnodelist.GetSize();i++) AddNode(newnodelist[i],d);
|
|
|
|
// put in all of the lines;
|
|
for(i=0;i<newlinelist.GetSize();i++)
|
|
{
|
|
p0.Set(newnodelist[newlinelist[i].n0].x,newnodelist[newlinelist[i].n0].y);
|
|
p1.Set(newnodelist[newlinelist[i].n1].x,newnodelist[newlinelist[i].n1].y);
|
|
AddSegment(p0,p1,newlinelist[i]);
|
|
}
|
|
|
|
// put in all of the arcs;
|
|
for(i=0;i<newarclist.GetSize();i++)
|
|
{
|
|
p0.Set(newnodelist[newarclist[i].n0].x,newnodelist[newarclist[i].n0].y);
|
|
p1.Set(newnodelist[newarclist[i].n1].x,newnodelist[newarclist[i].n1].y);
|
|
AddArcSegment(p0,p1,newarclist[i]);
|
|
}
|
|
|
|
// put in all of the block labels;
|
|
for(i=0;i<newblocklist.GetSize();i++) AddBlockLabel(newblocklist[i],d);
|
|
|
|
UnselectAll();
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL ChdrawDoc::AddNode(CNode &node, double d)
|
|
{
|
|
int i,k;
|
|
CSegment segm;
|
|
CArcSegment asegm;
|
|
CComplex c,a0,a1,a2;
|
|
double x,y;
|
|
double R;
|
|
|
|
x=node.x; y=node.y;
|
|
|
|
// test to see if ``too close'' to existing node...
|
|
for (i=0;i<nodelist.GetSize();i++)
|
|
if(nodelist[i].GetDistance(x,y)<d) return FALSE;
|
|
|
|
// can't put a node on top of a block label; do same sort of test.
|
|
for (i=0;i<blocklist.GetSize();i++)
|
|
if(blocklist[i].GetDistance(x,y)<d) return FALSE;
|
|
|
|
// if all is OK, add point in to the node list...
|
|
nodelist.Add(node);
|
|
|
|
// test to see if node is on an existing line; if so,
|
|
// break into two lines;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if (fabs(ShortestDistance(x,y,i))<d)
|
|
{
|
|
segm=linelist[i];
|
|
linelist[i].n1=(int) nodelist.GetSize()-1;
|
|
segm.n0=(int) nodelist.GetSize()-1;
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
|
|
// test to see if node is on an existing arc; if so,
|
|
// break into two arcs;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if (ShortestDistanceFromArc(CComplex(x,y),arclist[i])<d)
|
|
{
|
|
a0.Set(nodelist[arclist[i].n0].x,nodelist[arclist[i].n0].y);
|
|
a1.Set(nodelist[arclist[i].n1].x,nodelist[arclist[i].n1].y);
|
|
a2.Set(x,y);
|
|
GetCircle(arclist[i],c,R);
|
|
asegm=arclist[i];
|
|
arclist[i].n1=(int) nodelist.GetSize()-1;
|
|
arclist[i].ArcLength=arg((a2-c)/(a0-c))*180./PI;
|
|
asegm.n0=(int) nodelist.GetSize()-1;
|
|
asegm.ArcLength=arg((a1-c)/(a2-c))*180./PI;
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ChdrawDoc::AddSegment(CComplex p0, CComplex p1, CSegment &segm, double tol)
|
|
{
|
|
int i,j,k,n0,n1;
|
|
double xi,yi,t;
|
|
CComplex p[2];
|
|
CArray< CComplex, CComplex&> newnodes;
|
|
|
|
newnodes.RemoveAll();
|
|
|
|
n0=ClosestNode(p0.re,p0.im);
|
|
n1=ClosestNode(p1.re,p1.im);
|
|
|
|
// don't add if line is degenerate
|
|
if (n0==n1) return FALSE;
|
|
|
|
// don't add if the line is already in the list;
|
|
for(i=0;i<linelist.GetSize();i++){
|
|
if ((linelist[i].n0==n0) && (linelist[i].n1==n1)) return FALSE;
|
|
if ((linelist[i].n0==n1) && (linelist[i].n1==n0)) return FALSE;
|
|
}
|
|
|
|
segm.IsSelected=FALSE; segm.n0=n0; segm.n1=n1;
|
|
|
|
// check to see if there are intersections with segments
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
if(GetIntersection(n0,n1,i,&xi,&yi)==TRUE) newnodes.Add(CComplex(xi,yi));
|
|
|
|
// check to see if there are intersections with arcs
|
|
for(i=0;i<arclist.GetSize();i++){
|
|
j=GetLineArcIntersection(segm,arclist[i],p);
|
|
if (j>0) for(k=0;k<j;k++) newnodes.Add(p[k]);
|
|
}
|
|
|
|
// add nodes at intersections
|
|
if(tol==0)
|
|
{
|
|
if (nodelist.GetSize()<2) t=1.e-08;
|
|
else{
|
|
CComplex p0,p1;
|
|
p0=nodelist[0].CC();
|
|
p1=p0;
|
|
for(i=1;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].x<p0.re) p0.re=nodelist[i].x;
|
|
if(nodelist[i].x>p1.re) p1.re=nodelist[i].x;
|
|
if(nodelist[i].y<p0.im) p0.im=nodelist[i].y;
|
|
if(nodelist[i].y>p1.im) p1.im=nodelist[i].y;
|
|
}
|
|
t=abs(p1-p0)*CLOSE_ENOUGH;
|
|
}
|
|
}
|
|
else t=tol;
|
|
|
|
for(i=0;i<newnodes.GetSize();i++)
|
|
AddNode(newnodes[i].re,newnodes[i].im,t);
|
|
|
|
// Add proposed line segment
|
|
linelist.Add(segm);
|
|
|
|
// check to see if proposed line passes through other points;
|
|
// if so, delete line and create lines that link intermediate points;
|
|
// does this by recursive use of AddSegment;
|
|
double d,dmin;
|
|
UnselectAll();
|
|
if (tol==0) dmin=abs(nodelist[n1].CC()-nodelist[n0].CC())*1.e-05;
|
|
else dmin=tol;
|
|
|
|
k=(int) linelist.GetSize()-1;
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if( (i!=n0) && (i!=n1) )
|
|
{
|
|
d=ShortestDistance(nodelist[i].x,nodelist[i].y,k);
|
|
// catch a special case...
|
|
if (abs(nodelist[i].CC()-nodelist[n0].CC())<dmin) d=2.*dmin;
|
|
if (abs(nodelist[i].CC()-nodelist[n1].CC())<dmin) d=2.*dmin;
|
|
if (d<dmin){
|
|
linelist[k].ToggleSelect();
|
|
DeleteSelectedSegments();
|
|
AddSegment(n0,i,&segm,dmin);
|
|
AddSegment(i,n1,&segm,dmin);
|
|
i=(int) nodelist.GetSize();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL ChdrawDoc::AddArcSegment(CComplex p0, CComplex p1, CArcSegment &asegm, double tol)
|
|
{
|
|
int i,j,k;
|
|
CSegment segm;
|
|
CArcSegment newarc;
|
|
CComplex c,p[2];
|
|
CArray< CComplex, CComplex&> newnodes;
|
|
double R,d,dmin,t;
|
|
|
|
asegm.n0=ClosestNode(p0.re,p0.im);
|
|
asegm.n1=ClosestNode(p1.re,p1.im);
|
|
|
|
newnodes.RemoveAll();
|
|
|
|
// don't add if line is degenerate
|
|
if (asegm.n0==asegm.n1) return FALSE;
|
|
|
|
// don't add if the arc is already in the list;
|
|
for(i=0;i<arclist.GetSize();i++){
|
|
if ((arclist[i].n0==asegm.n0) && (arclist[i].n1==asegm.n1) &&
|
|
(fabs(arclist[i].ArcLength-asegm.ArcLength)<1.e-02)) return FALSE;
|
|
// arcs are ``the same'' if start and end points are the same, and if
|
|
// the arc lengths are relatively close (but a lot farther than
|
|
// machine precision...
|
|
}
|
|
|
|
// add proposed arc to the linelist
|
|
asegm.IsSelected=FALSE;
|
|
|
|
// check to see if there are intersections
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
j=GetLineArcIntersection(linelist[i],asegm,p);
|
|
if(j>0) for(k=0;k<j;k++) newnodes.Add(p[k]);
|
|
}
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
j=GetArcArcIntersection(asegm,arclist[i],p);
|
|
if(j>0) for(k=0;k<j;k++) newnodes.Add(p[k]);
|
|
}
|
|
|
|
// add nodes at intersections
|
|
if (tol==0)
|
|
{
|
|
if (nodelist.GetSize()<2) t=1.e-08;
|
|
else{
|
|
CComplex p0,p1;
|
|
p0=nodelist[0].CC();
|
|
p1=p0;
|
|
for(i=1;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].x<p0.re) p0.re=nodelist[i].x;
|
|
if(nodelist[i].x>p1.re) p1.re=nodelist[i].x;
|
|
if(nodelist[i].y<p0.im) p0.im=nodelist[i].y;
|
|
if(nodelist[i].y>p1.im) p1.im=nodelist[i].y;
|
|
}
|
|
t=abs(p1-p0)*CLOSE_ENOUGH;
|
|
}
|
|
}
|
|
else t=tol;
|
|
|
|
for(i=0;i<newnodes.GetSize();i++)
|
|
AddNode(newnodes[i].re,newnodes[i].im,t);
|
|
|
|
// add proposed arc segment;
|
|
arclist.Add(asegm);
|
|
|
|
// check to see if proposed arc passes through other points;
|
|
// if so, delete arc and create arcs that link intermediate points;
|
|
// does this by recursive use of AddArcSegment;
|
|
UnselectAll();
|
|
GetCircle(asegm,c,R);
|
|
if (tol==0) dmin=fabs(R*PI*asegm.ArcLength/180.)*1.e-05;
|
|
else dmin=tol;
|
|
k=(int) arclist.GetSize()-1;
|
|
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if( (i!=asegm.n0) && (i!=asegm.n1) )
|
|
{
|
|
d=ShortestDistanceFromArc(CComplex(nodelist[i].x,nodelist[i].y), arclist[k]);
|
|
if (d<dmin){
|
|
CComplex a0,a1,a2;
|
|
a0.Set(nodelist[asegm.n0].x,nodelist[asegm.n0].y);
|
|
a1.Set(nodelist[asegm.n1].x,nodelist[asegm.n1].y);
|
|
a2.Set(nodelist[i].x,nodelist[i].y);
|
|
arclist[k].ToggleSelect();
|
|
DeleteSelectedArcSegments();
|
|
|
|
newarc=asegm;
|
|
newarc.n1=i;
|
|
newarc.ArcLength=arg((a2-c)/(a0-c))*180./PI;
|
|
AddArcSegment(newarc,dmin);
|
|
|
|
newarc=asegm;
|
|
newarc.n0=i;
|
|
newarc.ArcLength=arg((a1-c)/(a2-c))*180./PI;
|
|
AddArcSegment(newarc,dmin);
|
|
|
|
i=(int) nodelist.GetSize();
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ChdrawDoc::AddBlockLabel(CBlockLabel &blabel, double d)
|
|
{
|
|
int i;
|
|
double x,y;
|
|
BOOL AddFlag=TRUE;
|
|
|
|
x=blabel.x; y=blabel.y;
|
|
|
|
// test to see if ``too close'' to existing node...
|
|
for (i=0;i<blocklist.GetSize();i++)
|
|
if(blocklist[i].GetDistance(x,y)<d) AddFlag=FALSE;
|
|
|
|
// can't put a block label on top of an existing node...
|
|
for (i=0;i<nodelist.GetSize();i++)
|
|
if(nodelist[i].GetDistance(x,y)<d) return FALSE;
|
|
|
|
// can't put a block label on a line, either...
|
|
for (i=0;i<linelist.GetSize();i++)
|
|
if(ShortestDistance(x,y,i)<d) return FALSE ;
|
|
|
|
// if all is OK, add point in to the node list...
|
|
if(AddFlag==TRUE) blocklist.Add(blabel);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL ChdrawDoc::WriteDXF(CString fname)
|
|
{
|
|
int i,j,k;
|
|
double x0,y0,x1,y1,R,dt;
|
|
double extmaxx,extminx,extmaxy,extminy;
|
|
BOOL laze[256];
|
|
int nlaze;
|
|
char lay[256];
|
|
CComplex c,p,s;
|
|
FILE *fp;
|
|
|
|
if ((fp=fopen(fname,"wt"))==NULL) return FALSE;
|
|
|
|
if (nodelist.GetSize()<2){
|
|
extmaxx=1;
|
|
extmaxy=1;
|
|
extminx=0;
|
|
extminy=0;
|
|
}
|
|
else{
|
|
extminx=nodelist[0].x;
|
|
extminy=nodelist[1].y;
|
|
extmaxx=extminx;
|
|
extmaxy=extminy;
|
|
for(i=1;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].x<extminx) extminx=nodelist[i].x;
|
|
if(nodelist[i].x>extmaxx) extmaxx=nodelist[i].x;
|
|
if(nodelist[i].y<extminy) extminy=nodelist[i].y;
|
|
if(nodelist[i].y>extmaxy) extmaxy=nodelist[i].y;
|
|
}
|
|
|
|
}
|
|
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
k=(int) ceil(arclist[i].ArcLength/arclist[i].MaxSideLength);
|
|
dt=arclist[i].ArcLength*PI/(((double) k)*180.);
|
|
GetCircle(arclist[i],c,R);
|
|
p.Set(nodelist[arclist[i].n0].x,nodelist[arclist[i].n0].y);
|
|
s=exp(I*dt);
|
|
for(j=0;j<k;j++){
|
|
p=(p-c)*s+c;
|
|
if(p.re<extminx) extminx=p.re;
|
|
if(p.re>extmaxx) extmaxx=p.re;
|
|
if(p.im<extminy) extminy=p.im;
|
|
if(p.im>extmaxy) extmaxy=p.im;
|
|
}
|
|
}
|
|
|
|
p.Set(extminx,extminy); s.Set(extmaxx,extmaxy);
|
|
R=0.025*abs(s-p);
|
|
|
|
// check out which layers are actually called out;
|
|
for(i=0,nlaze=0;i<256;i++) laze[i]=FALSE;
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
if(linelist[i].InGroup!=0)
|
|
{
|
|
for(j=0,k=FALSE;j<nlaze;j++)
|
|
{
|
|
if(laze[j]==linelist[i].InGroup)
|
|
{
|
|
k=TRUE;
|
|
j=nlaze;
|
|
}
|
|
}
|
|
if((k==FALSE) && (nlaze<256)){
|
|
laze[nlaze]=linelist[i].InGroup;
|
|
nlaze++;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
if(arclist[i].InGroup!=0)
|
|
{
|
|
for(j=0,k=FALSE;j<nlaze;j++)
|
|
{
|
|
if(laze[j]==arclist[i].InGroup)
|
|
{
|
|
k=TRUE;
|
|
j=nlaze;
|
|
}
|
|
}
|
|
if((k==FALSE) && (nlaze<256)){
|
|
laze[nlaze]=arclist[i].InGroup;
|
|
nlaze++;
|
|
}
|
|
}
|
|
|
|
fprintf(fp," 0\nSECTION\n 2\nHEADER\n 9\n");
|
|
fprintf(fp,"$INSBASE\n 10\n0.0000\n 20\n0.0000\n 9\n");
|
|
fprintf(fp,"$EXTMIN\n 10\n%.17g\n 20\n%.17g\n 9\n",extminx-R,extminy-R);
|
|
fprintf(fp,"$EXTMAX\n 10\n%.17g\n 20\n%.17g\n 9\n",extmaxx+R,extmaxy+R);
|
|
fprintf(fp,"$LIMMIN\n 10\n%.17g\n 20\n%.17g\n 9\n",extminx-R,extminy-R);
|
|
fprintf(fp,"$LIMMAX\n 10\n%.17g\n 20\n%.17g\n 9\n",extmaxx+R,extmaxy+R);
|
|
fprintf(fp,"$TEXTSTYLE\n 7\nSTANDARD\n 9\n$CLAYER\n");
|
|
fprintf(fp," 8\ndefault\n 0\nENDSEC\n 0\n");
|
|
fprintf(fp,"SECTION\n 2\nTABLES\n 0\n");
|
|
fprintf(fp,"TABLE\n 2\nLTYPE\n 70\n4948253\n 0\n");
|
|
fprintf(fp,"LTYPE\n 2\nCONTINUOUS\n 70\n 64\n 3\n");
|
|
fprintf(fp,"Solid line\n 72\n 65\n 73\n 0\n 40\n0.0\n 0\nENDTAB\n 0\n");
|
|
fprintf(fp,"TABLE\n 2\nLAYER\n 70\n 5\n 0\n");
|
|
fprintf(fp,"LAYER\n 2\ndefault\n 70\n 64\n 62\n 7\n 6\n");
|
|
fprintf(fp,"CONTINUOUS\n 0\n");
|
|
|
|
for(i=0;i<nlaze;i++)
|
|
{
|
|
fprintf(fp,"LAYER\n 2\nlayer%i\n 70\n 64\n 62\n 7\n 6\n",laze[i]);
|
|
fprintf(fp,"CONTINUOUS\n 0\n");
|
|
}
|
|
|
|
fprintf(fp,"ENDTAB\n 0\nTABLE\n 2\n");
|
|
fprintf(fp,"STYLE\n 70\n 1\n 0\nSTYLE\n 2\nSTANDARD\n 70\n");
|
|
fprintf(fp," 0\n 40\n0.0\n 41\n1.0\n 50\n0.0\n 71\n 0\n");
|
|
fprintf(fp," 42\n0.2\n 3\ntxt\n 4\n\n 0\nENDTAB\n 0\n");
|
|
fprintf(fp,"TABLE\n 2\nVIEW\n 70\n 0\n 0\nENDTAB\n 0\n");
|
|
fprintf(fp,"ENDSEC\n 0\nSECTION\n 2\nBLOCKS\n 0\nENDSEC\n");
|
|
fprintf(fp," 0\nSECTION\n 2\nENTITIES\n 0\n");
|
|
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
x0=nodelist[linelist[i].n0].x;
|
|
y0=nodelist[linelist[i].n0].y;
|
|
x1=nodelist[linelist[i].n1].x;
|
|
y1=nodelist[linelist[i].n1].y;
|
|
if (linelist[i].InGroup==0) sprintf(lay,"default");
|
|
else sprintf(lay,"layer%i",linelist[i].InGroup);
|
|
fprintf(fp,"LINE\n 8\n%s\n 10\n%.17g\n 20\n%.17g\n 30\n0.0\n 11\n%.17g\n 21\n%.17g\n 31\n0.0\n 0\n",
|
|
lay,x0,y0,x1,y1);
|
|
}
|
|
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
GetCircle(arclist[i],c,R);
|
|
x0=arg(nodelist[arclist[i].n0].CC()-c)*180./PI;
|
|
x1=arg(nodelist[arclist[i].n1].CC()-c)*180./PI;
|
|
if (x0<0) x0+=360.;
|
|
if (x1<0) x1+=360.;
|
|
if (arclist[i].InGroup==0) sprintf(lay,"default");
|
|
else sprintf(lay,"layer%i",arclist[i].InGroup);
|
|
fprintf(fp,"ARC\n 8\n%s\n",lay);
|
|
fprintf(fp," 10\n%.17g\n 20\n%.17g\n 30\n%.17g\n 40\n%.17g\n 50\n%.17g\n 51\n%.17g\n 0\n",
|
|
c.re,c.im,0.,R,x0,x1);
|
|
}
|
|
|
|
fprintf(fp,"ENDSEC\n 0\nEOF\n");
|
|
|
|
fclose(fp);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void ChdrawDoc::ScaleMove(double bx, double by, double sf, int EditAction)
|
|
{
|
|
int i;
|
|
|
|
if(EditAction==0)
|
|
{
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
nodelist[i].x=bx+sf*(nodelist[i].x-bx);
|
|
nodelist[i].y=by+sf*(nodelist[i].y-by);
|
|
}
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
if(EditAction==1)
|
|
{
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
nodelist[linelist[i].n0].IsSelected=TRUE;
|
|
nodelist[linelist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
ScaleMove(bx,by,sf,0);
|
|
return;
|
|
}
|
|
|
|
if(EditAction==2)
|
|
{
|
|
for(i=0;i<blocklist.GetSize();i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
blocklist[i].x=bx+sf*(blocklist[i].x-bx);
|
|
blocklist[i].y=by+sf*(blocklist[i].y-by);
|
|
blocklist[i].MaxArea*=(sf*sf);
|
|
}
|
|
}
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
if(EditAction==3)
|
|
{
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
nodelist[arclist[i].n0].IsSelected=TRUE;
|
|
nodelist[arclist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
ScaleMove(bx,by,sf,0);
|
|
return;
|
|
}
|
|
|
|
if(EditAction==4)
|
|
{
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
nodelist[linelist[i].n0].IsSelected=TRUE;
|
|
nodelist[linelist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
nodelist[arclist[i].n0].IsSelected=TRUE;
|
|
nodelist[arclist[i].n1].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<nodelist.GetSize();i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
nodelist[i].x=bx+sf*(nodelist[i].x-bx);
|
|
nodelist[i].y=by+sf*(nodelist[i].y-by);
|
|
}
|
|
}
|
|
|
|
for(i=0;i<blocklist.GetSize();i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
blocklist[i].x=bx+sf*(blocklist[i].x-bx);
|
|
blocklist[i].y=by+sf*(blocklist[i].y-by);
|
|
blocklist[i].MaxArea*=(sf*sf);
|
|
}
|
|
}
|
|
|
|
EnforcePSLG();
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void ChdrawDoc::MirrorSelected(double x0, double y0, double x1, double y1, int EditAction)
|
|
{
|
|
int i,j,k;
|
|
CComplex x,p,y;
|
|
|
|
x=x0 + I*y0;
|
|
p=(x1-x0) + I*(y1-y0);
|
|
if(abs(p)==0) return;
|
|
p/=abs(p);
|
|
|
|
if(EditAction==0)
|
|
{
|
|
CNode node;
|
|
k=(int) nodelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
node=nodelist[i];
|
|
y=((node.x + I*node.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
node.x=y.re;
|
|
node.y=y.im;
|
|
node.IsSelected=FALSE;
|
|
nodelist.Add(node);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==1)
|
|
{
|
|
CSegment segm;
|
|
CNode n0,n1;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
n0=nodelist[linelist[i].n0];
|
|
n1=nodelist[linelist[i].n1];
|
|
|
|
y=((n0.x + I*n0.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n0.x=y.re;
|
|
n0.y=y.im;
|
|
|
|
y=((n1.x + I*n1.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n1.x=y.re;
|
|
n1.y=y.im;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
segm=linelist[i];
|
|
segm.n0=j; segm.n1=j+1;
|
|
segm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==2)
|
|
{
|
|
CBlockLabel lbl;
|
|
k=(int) blocklist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
lbl=blocklist[i];
|
|
y=((lbl.x + I*lbl.y)-x)/p;
|
|
y=p*y.Conj()+x;
|
|
lbl.x=y.re;
|
|
lbl.y=y.im;
|
|
lbl.IsSelected=FALSE;
|
|
blocklist.Add(lbl);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(EditAction==3)
|
|
{
|
|
CArcSegment asegm;
|
|
CNode n0,n1;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
n0=nodelist[arclist[i].n1];
|
|
n1=nodelist[arclist[i].n0];
|
|
|
|
y=((n0.x + I*n0.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n0.x=y.re;
|
|
n0.y=y.im;
|
|
n0.IsSelected=FALSE;
|
|
|
|
y=((n1.x + I*n1.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n1.x=y.re;
|
|
n1.y=y.im;
|
|
n1.IsSelected=FALSE;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
asegm=arclist[i];
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(EditAction==4)
|
|
{
|
|
CNode node;
|
|
k=(int) nodelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(nodelist[i].IsSelected==TRUE){
|
|
node=nodelist[i];
|
|
y=((node.x + I*node.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
node.x=y.re;
|
|
node.y=y.im;
|
|
node.IsSelected=FALSE;
|
|
nodelist.Add(node);
|
|
}
|
|
}
|
|
|
|
CSegment segm;
|
|
CNode n0,n1;
|
|
k=(int) linelist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(linelist[i].IsSelected==TRUE){
|
|
n0=nodelist[linelist[i].n0];
|
|
n1=nodelist[linelist[i].n1];
|
|
|
|
y=((n0.x + I*n0.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n0.x=y.re;
|
|
n0.y=y.im;
|
|
|
|
y=((n1.x + I*n1.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n1.x=y.re;
|
|
n1.y=y.im;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
segm=linelist[i];
|
|
segm.n0=j; segm.n1=j+1;
|
|
segm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
linelist.Add(segm);
|
|
}
|
|
}
|
|
|
|
CBlockLabel lbl;
|
|
k=(int) blocklist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(blocklist[i].IsSelected==TRUE){
|
|
lbl=blocklist[i];
|
|
y=((lbl.x + I*lbl.y)-x)/p;
|
|
y=p*y.Conj()+x;
|
|
lbl.x=y.re;
|
|
lbl.y=y.im;
|
|
lbl.IsSelected=FALSE;
|
|
blocklist.Add(lbl);
|
|
}
|
|
}
|
|
|
|
CArcSegment asegm;
|
|
k=(int) arclist.GetSize();
|
|
for(i=0;i<k;i++)
|
|
{
|
|
if(arclist[i].IsSelected==TRUE){
|
|
n0=nodelist[arclist[i].n1];
|
|
n1=nodelist[arclist[i].n0];
|
|
|
|
y=((n0.x + I*n0.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n0.x=y.re;
|
|
n0.y=y.im;
|
|
n0.IsSelected=FALSE;
|
|
|
|
y=((n1.x + I*n1.y) - x)/p;
|
|
y=p*y.Conj()+x;
|
|
n1.x=y.re;
|
|
n1.y=y.im;
|
|
n1.IsSelected=FALSE;
|
|
|
|
j=(int) nodelist.GetSize();
|
|
asegm=arclist[i];
|
|
asegm.n0=j; asegm.n1=j+1;
|
|
asegm.IsSelected=FALSE;
|
|
nodelist.Add(n0);
|
|
nodelist.Add(n1);
|
|
arclist.Add(asegm);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
EnforcePSLG();
|
|
return;
|
|
}
|
|
|
|
BOOL ChdrawDoc::dxf_line_hook()
|
|
{
|
|
MSG msg;
|
|
|
|
while ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
|
|
{
|
|
if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE))
|
|
{
|
|
MessageBeep(MB_ICONEXCLAMATION);
|
|
return TRUE;
|
|
}
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void ChdrawDoc::FancyEnforcePSLG(double tol)
|
|
{
|
|
/*
|
|
need to enforce:
|
|
1) no duplicate point;
|
|
2) no intersections between line segments, lines and arcs, or arcs;
|
|
3) no duplicate block labels;
|
|
4) no overlapping lines or arcs.
|
|
|
|
can do this by cleaning out the various lists, and rebuilding them
|
|
using the ``add'' functions that ensure that things come out right.
|
|
*/
|
|
|
|
CArray< CNode, CNode&> newnodelist;
|
|
CArray< CSegment, CSegment&> newlinelist;
|
|
CArray< CArcSegment, CArcSegment&> newarclist;
|
|
CArray< CBlockLabel, CBlockLabel&> newblocklist;
|
|
int i,k;
|
|
CComplex p0,p1;
|
|
double d;
|
|
|
|
bLinehook=ImportDXF; // kludge to stop the program from giving a crash if
|
|
// the user tries to exit during a dxf import.
|
|
|
|
ChdrawView *pView;
|
|
POSITION pos;
|
|
pos=GetFirstViewPosition();
|
|
pView=(ChdrawView *)GetNextView(pos);
|
|
|
|
FirstDraw=TRUE;
|
|
// pView->lua_zoomnatural();
|
|
dxf_line_hook();
|
|
pView->EditAction=4;
|
|
|
|
newnodelist.RemoveAll();
|
|
newlinelist.RemoveAll();
|
|
newarclist.RemoveAll();
|
|
newblocklist.RemoveAll();
|
|
|
|
for(i=0;i<nodelist.GetSize();i++) newnodelist.Add(nodelist[i]);
|
|
for(i=0;i<linelist.GetSize();i++) newlinelist.Add(linelist[i]);
|
|
for(i=0;i<arclist.GetSize();i++) newarclist.Add(arclist[i]);
|
|
for(i=0;i<blocklist.GetSize();i++) newblocklist.Add(blocklist[i]);
|
|
|
|
nodelist.RemoveAll();
|
|
linelist.RemoveAll();
|
|
arclist.RemoveAll();
|
|
blocklist.RemoveAll();
|
|
|
|
pView->InvalidateRect(NULL);
|
|
dxf_line_hook();
|
|
|
|
// find out what tolerance is so that there are not nodes right on
|
|
// top of each other;
|
|
if(tol==0){
|
|
if (newnodelist.GetSize()<2) d=1.e-08;
|
|
else{
|
|
p0=newnodelist[0].CC();
|
|
p1=p0;
|
|
for(i=1;i<newnodelist.GetSize();i++)
|
|
{
|
|
if(newnodelist[i].x<p0.re) p0.re=newnodelist[i].x;
|
|
if(newnodelist[i].x>p1.re) p1.re=newnodelist[i].x;
|
|
if(newnodelist[i].y<p0.im) p0.im=newnodelist[i].y;
|
|
if(newnodelist[i].y>p1.im) p1.im=newnodelist[i].y;
|
|
}
|
|
d=abs(p1-p0)*CLOSE_ENOUGH;
|
|
}
|
|
}
|
|
else d=tol;
|
|
|
|
// put in all of the lines;
|
|
for(i=0;i<newlinelist.GetSize();i++)
|
|
{
|
|
// Add in endpoints of the proposed line;
|
|
AddNode(newnodelist[newlinelist[i].n0],d);
|
|
AddNode(newnodelist[newlinelist[i].n1],d);
|
|
|
|
// Add in the proposed line itself;
|
|
p0=newnodelist[newlinelist[i].n0].CC();
|
|
p1=newnodelist[newlinelist[i].n1].CC();
|
|
if(AddSegment(p0,p1,newlinelist[i],d)==TRUE)
|
|
{
|
|
pView->DrawPSLG();
|
|
if(dxf_line_hook()){
|
|
bLinehook=FALSE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// put in all of the arcs;
|
|
for(i=0;i<newarclist.GetSize();i++)
|
|
{
|
|
|
|
// Add in endpoints of the proposed line;
|
|
AddNode(newnodelist[newarclist[i].n0],d);
|
|
AddNode(newnodelist[newarclist[i].n1],d);
|
|
|
|
// Add in the proposed arc inself;
|
|
p0=newnodelist[newarclist[i].n0].CC();
|
|
p1=newnodelist[newarclist[i].n1].CC();
|
|
if(AddArcSegment(p0,p1,newarclist[i],d)==TRUE)
|
|
{
|
|
pView->DrawPSLG();
|
|
if(dxf_line_hook()){
|
|
bLinehook=FALSE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
UnselectAll();
|
|
|
|
// do one last check to eliminate shallow arcs that
|
|
// link up the same two points as a line segment;
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if (arclist[i].ArcLength<=22.5)
|
|
{
|
|
for(k=0;k<linelist.GetSize();k++)
|
|
{
|
|
if ((arclist[i].n0==linelist[k].n0) &&
|
|
(arclist[i].n1==linelist[k].n1))
|
|
arclist[i].IsSelected=TRUE;
|
|
if ((arclist[i].n1==linelist[k].n0) &&
|
|
(arclist[i].n0==linelist[k].n1))
|
|
arclist[i].IsSelected=TRUE;
|
|
if (arclist[i].IsSelected) k=(int) linelist.GetSize();
|
|
}
|
|
}
|
|
}
|
|
DeleteSelectedArcSegments();
|
|
|
|
// put in all of the block labels;
|
|
for(i=0;i<newblocklist.GetSize();i++) AddBlockLabel(newblocklist[i],d);
|
|
|
|
if(SelectOrphans())
|
|
{
|
|
CString msg;
|
|
msg ="There are lines or arcs with \"Orphaned\" end points.\n";
|
|
msg+="The lines or arcs could be glitches in the DXF import\n";
|
|
msg+="import, so they should be examined manually.\n";
|
|
msg+="These points and lines will be shown as selected.\n";
|
|
msg+="To redisplay the orphaned points and lines, select\n";
|
|
msg+="View|Show Orphans off of the main menu.";
|
|
MsgBox(msg);
|
|
}
|
|
|
|
bLinehook=FALSE;
|
|
|
|
return;
|
|
}
|
|
|
|
BOOL ChdrawDoc::SelectOrphans()
|
|
{
|
|
int i;
|
|
BOOL bHasOrphans;
|
|
|
|
UnselectAll();
|
|
|
|
// figure out if there are any orphan segments or arcs
|
|
// and select them so that the will be visible to the user
|
|
// We will first figure out which nodes are elements of only
|
|
// one line or arc. Then, we will select the lines and arcs
|
|
// that are associated with these orphaned nodes
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
nodelist[linelist[i].n0].IsSelected++;
|
|
nodelist[linelist[i].n1].IsSelected++;
|
|
}
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
nodelist[arclist[i].n0].IsSelected++;
|
|
nodelist[arclist[i].n1].IsSelected++;
|
|
}
|
|
for(i=0,bHasOrphans=FALSE;i<nodelist.GetSize();i++)
|
|
{
|
|
if (nodelist[i].IsSelected!=1) nodelist[i].IsSelected=FALSE;
|
|
else bHasOrphans=TRUE;
|
|
}
|
|
if(bHasOrphans)
|
|
{
|
|
// We _have_ orphaned nodes. Select their associated
|
|
// lines and/or arcs, and give the user a message about it.
|
|
for(i=0;i<linelist.GetSize();i++)
|
|
{
|
|
if(nodelist[linelist[i].n0].IsSelected)
|
|
linelist[i].IsSelected=TRUE;
|
|
if(nodelist[linelist[i].n1].IsSelected)
|
|
linelist[i].IsSelected=TRUE;
|
|
}
|
|
for(i=0;i<arclist.GetSize();i++)
|
|
{
|
|
if(nodelist[arclist[i].n0].IsSelected)
|
|
arclist[i].IsSelected=TRUE;
|
|
if(nodelist[arclist[i].n1].IsSelected)
|
|
arclist[i].IsSelected=TRUE;
|
|
}
|
|
}
|
|
|
|
return bHasOrphans;
|
|
}
|