1 {
2 *****************************************************************************
3 * *
4 * This file is part of the ZCAD *
5 * *
6 * See the file COPYING.modifiedLGPL.txt, included in this distribution, *
7 * for details about the copyright. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
12 * *
13 *****************************************************************************
14 }
15 {
16 @author(Andrey Zubarev <zamtmn@yandex.ru>)
17 }
18 unit uzeentellipse;
19 {$INCLUDE def.inc}
20 interface
21 uses
22 uzeentityfactory,uzeentsubordinated,uzgldrawcontext,uzedrawingdef,uzecamera,
23 uzeentwithlocalcs,gzctnrvectorpobjects,uzestyleslayers,uzbtypesbase,
24 UGDBSelectedObjArray,uzeentity,UGDBOutbound2DIArray,UGDBPoint3DArray,
25 uzbgeomtypes,UGDBOpenArrayOfByte,varman,varmandef,uzbtypes,uzeconsts,
26 uzglviewareadata,uzegeometry,uzeffdxfsupport,uzbmemman,uzeentplain;
27 type
28 {REGISTEROBJECTTYPE GDBObjEllipse}
29 {Export+}
30 ptEllipsertmodify=^tEllipsertmodify;
31 tEllipsertmodify=packed record
32 p1,p2,p3:GDBVertex2d;
33 end;
34 PGDBObjEllipse=^GDBObjEllipse;
35 GDBObjEllipse={$IFNDEF DELPHI}packed{$ENDIF} object(GDBObjPlain)
36 RR:GDBDouble;(*saved_to_shd*)
37 MajorAxis:GDBvertex;
38 Ratio:GDBDouble;(*saved_to_shd*)
39 StartAngle:GDBDouble;(*saved_to_shd*)
40 EndAngle:GDBDouble;(*saved_to_shd*)
41 angle:GDBDouble;
42 Vertex3D_in_WCS_Array:GDBPoint3DArray;
43 length:GDBDouble;
44 q0,q1,q2:GDBvertex;
45 pq0,pq1,pq2:GDBvertex;
46 constructor init(own:GDBPointer;layeraddres:PGDBLayerProp;LW:GDBSmallint;p:GDBvertex;{RR,}S,E:GDBDouble;majaxis:GDBVertex);
47 constructor initnul;
48 procedure LoadFromDXF(var f:GDBOpenArrayOfByte;ptu:PExtensionData;var drawing:TDrawingDef);virtual;
49
50 procedure SaveToDXF(var outhandle:{GDBInteger}GDBOpenArrayOfByte;var drawing:TDrawingDef;var IODXFContext:TIODXFContext);virtual;
51 procedure DrawGeometry(lw:GDBInteger;var DC:TDrawContext{infrustumactualy:TActulity;subrender:GDBInteger});virtual;
52 procedure addcontrolpoints(tdesc:GDBPointer);virtual;
53 procedure remaponecontrolpoint(pdesc:pcontrolpointdesc);virtual;
54 procedure CalcObjMatrix;virtual;
55 procedure FormatEntity(var drawing:TDrawingDef;var DC:TDrawContext);virtual;
56 procedure createpoint;virtual;
57 procedure getoutbound(var DC:TDrawContext);virtual;
58 procedure RenderFeedback(pcount:TActulity;var camera:GDBObjCamera; ProjectProc:GDBProjectProc;var DC:TDrawContext);virtual;
59 procedure projectpoint;virtual;
onmousenull60 function onmouse(var popa:TZctnrVectorPGDBaseObjects;const MF:ClipArray;InSubEntry:GDBBoolean):GDBBoolean;virtual;
getsnapnull61 function getsnap(var osp:os_record; var pdata:GDBPointer; const param:OGLWndtype; ProjectProc:GDBProjectProc;SnapMode:TGDBOSMode):GDBBoolean;virtual;
beforertmodifynull62 function beforertmodify:GDBPointer;virtual;
63 procedure rtmodifyonepoint(const rtmod:TRTModifyData);virtual;
IsRTNeedModifynull64 function IsRTNeedModify(const Point:PControlPointDesc; p:GDBPointer):Boolean;virtual;
Clonenull65 function Clone(own:GDBPointer):PGDBObjEntity;virtual;
66 procedure rtsave(refp:GDBPointer);virtual;
67 destructor done;virtual;
GetObjTypeNamenull68 function GetObjTypeName:GDBString;virtual;
calcinfrustumnull69 function calcinfrustum(frustum:ClipArray;infrustumactualy:TActulity;visibleactualy:TActulity;var totalobj,infrustumobj:GDBInteger; ProjectProc:GDBProjectProc;const zoom,currentdegradationfactor:GDBDouble):GDBBoolean;virtual;
CalcTrueInFrustumnull70 function CalcTrueInFrustum(frustum:ClipArray;visibleactualy:TActulity):TInBoundingVolume;virtual;
CalcObjMatrixWithoutOwnernull71 function CalcObjMatrixWithoutOwner:DMatrix4D;virtual;
72 procedure transform(const t_matrix:DMatrix4D);virtual;
73 procedure TransformAt(p:PGDBObjEntity;t_matrix:PDMatrix4D);virtual;
74 procedure ReCalcFromObjMatrix;virtual;
75
CreateInstancenull76 function CreateInstance:PGDBObjEllipse;static;
GetObjTypenull77 function GetObjType:TObjID;virtual;
78 end;
79 {EXPORT-}
80 implementation
81 //uses log;
82 procedure GDBObjEllipse.TransformAt;
83 var
84 tv:GDBVertex4D;
85 begin
86 objmatrix:=uzegeometry.MatrixMultiply(PGDBObjWithLocalCS(p)^.objmatrix,t_matrix^);
87
88 tv:=PGDBVertex4D(@t_matrix[3])^;
89 PGDBVertex4D(@t_matrix[3])^:=NulVertex4D;
90 MajorAxis:=VectorTransform3D(PGDBObjEllipse(p)^.MajorAxis,t_matrix^);
91 PGDBVertex4D(@t_matrix[3])^:=tv;
92
93 {Local.oz:=PGDBVertex(@objmatrix[2])^;
94
95 Local.p_insert:=PGDBVertex(@objmatrix[3])^;}ReCalcFromObjMatrix;
96 end;
97 procedure GDBObjEllipse.transform;
98 var {tv,}tv2:GDBVertex4D;
99 begin
100 inherited;
101
102 tv2:=PGDBVertex4D(@t_matrix[3])^;
103 PGDBVertex4D(@t_matrix[3])^:=NulVertex4D;
104 MajorAxis:=VectorTransform3D(MajorAxis,t_matrix);
105 PGDBVertex4D(@t_matrix[3])^:=tv2;
106
107 ReCalcFromObjMatrix;
108 end;
109 procedure GDBObjEllipse.ReCalcFromObjMatrix;
110 //var
111 //ox:gdbvertex;
112 begin
113 inherited;
114 {Local.basis.ox:=PGDBVertex(@objmatrix[0])^;
115 Local.basis.oy:=PGDBVertex(@objmatrix[1])^;
116
117 Local.basis.ox:=normalizevertex(Local.basis.ox);
118 Local.basis.oy:=normalizevertex(Local.basis.oy);
119 Local.basis.oz:=normalizevertex(Local.basis.oz);}
120
121 Local.P_insert:=PGDBVertex(@objmatrix[3])^;
122
123
124 //scale.x:=uzegeometry.oneVertexlength(PGDBVertex(@objmatrix[0])^);
125 //scale.y:=uzegeometry.oneVertexlength(PGDBVertex(@objmatrix[1])^);
126 //scale.z:=uzegeometry.oneVertexlength(PGDBVertex(@objmatrix[2])^);
127
128 {if (abs (Local.basis.oz.x) < 1/64) and (abs (Local.basis.oz.y) < 1/64) then
129 ox:=CrossVertex(YWCS,Local.basis.oz)
130 else
131 ox:=CrossVertex(ZWCS,Local.basis.oz);}
132 //normalizevertex(ox);
133 //rotate:=uzegeometry.scalardot(Local.basis.ox,ox);
134 // rotate:=arccos(rotate)*180/pi;
135 //if local.basis.OX.y<-eps then rotate:=360-rotate;
136 end;
137
GDBObjEllipse.CalcObjMatrixWithoutOwnernull138 function GDBObjEllipse.CalcObjMatrixWithoutOwner;
139 var rotmatr,dispmatr{,m1}:DMatrix4D;
140 begin
141 //Local.oz:=NormalizeVertex(Local.oz);
142 Local.basis.ox:=MajorAxis;
143 Local.basis.oy:=CrossVertex(Local.basis.oz,Local.basis.ox);
144
145 Local.basis.ox:=NormalizeVertex(Local.basis.ox);
146 Local.basis.oy:=NormalizeVertex(Local.basis.oy);
147 Local.basis.oz:=NormalizeVertex(Local.basis.oz);
148
149 rotmatr:=onematrix;
150 PGDBVertex(@rotmatr[0])^:=Local.basis.ox;
151 PGDBVertex(@rotmatr[1])^:=Local.basis.oy;
152 PGDBVertex(@rotmatr[2])^:=Local.basis.oz;
153
154 dispmatr:=onematrix;
155 PGDBVertex(@dispmatr[3])^:=Local.p_insert;
156
157 result:=MatrixMultiply({dispmatr,}rotmatr,dispmatr);
158 end;
GDBObjEllipse.CalcTrueInFrustumnull159 function GDBObjEllipse.CalcTrueInFrustum;
160 var i{,count}:GDBInteger;
161 //d1,d2,d3,d4:gdbdouble;
162 begin
163 for i:=0 to 5 do
164 begin
165 if(frustum[i][0] * P_insert_in_WCS.x + frustum[i][1] * P_insert_in_WCS.y + frustum[i][2] * P_insert_in_WCS.z + frustum[i][3]+rr < 0 )
166 then
167 begin
168 result:=IREmpty;
169 exit;
170 //system.break;
171 end;
172 end;
173 result:=Vertex3D_in_WCS_Array.CalcTrueInFrustum(frustum);
174 end;
GDBObjEllipse.calcinfrustumnull175 function GDBObjEllipse.calcinfrustum;
176 var i:GDBInteger;
177 begin
178 result:=true;
179 for i:=0 to 4 do
180 begin
181 if(frustum[i][0] * outbound[0].x + frustum[i][1] * outbound[0].y + frustum[i][2] * outbound[0].z + frustum[i][3] < 0 )
182 and(frustum[i][0] * outbound[1].x + frustum[i][1] * outbound[1].y + frustum[i][2] * outbound[1].z + frustum[i][3] < 0 )
183 and(frustum[i][0] * outbound[2].x + frustum[i][1] * outbound[2].y + frustum[i][2] * outbound[2].z + frustum[i][3] < 0 )
184 and(frustum[i][0] * outbound[3].x + frustum[i][1] * outbound[3].y + frustum[i][2] * outbound[3].z + frustum[i][3] < 0 )
185 then
186 begin
187 result:=false;
188 system.break;
189 end;
190 end;
191 end;
GDBObjEllipse.GetObjTypeNamenull192 function GDBObjEllipse.GetObjTypeName;
193 begin
194 result:=ObjN_GDBObjEllipse;
195 end;
196 destructor GDBObjEllipse.done;
197 begin
198 inherited done;
199 //Vertex3D_in_WCS_Array.Clear;
200 Vertex3D_in_WCS_Array.Done;
201 end;
202 constructor GDBObjEllipse.initnul;
203 begin
204 startangle := 0;
205 endangle := 2*pi;
206 PProjoutbound:=nil;
207 majoraxis:=onevertex;
208 inherited initnul(nil);
209 //vp.ID:=GDBEllipseID;
210 //r := 1;
211 Vertex3D_in_WCS_Array.init({$IFDEF DEBUGBUILD}'{B591E6C2-9BD5-4099-BE5A-5CB3911661B7}',{$ENDIF}100);
212 end;
213 constructor GDBObjEllipse.init;
214 begin
215 inherited init(own,layeraddres, lw);
216 //vp.ID:=GDBEllipseID;
217 Local.p_insert := p;
218 //r := rr;
219 startangle := s;
220 endangle := e;
221 majoraxis:=majaxis;
222 PProjoutbound:=nil;
223 Vertex3D_in_WCS_Array.init({$IFDEF DEBUGBUILD}'{AEF4273C-4EE8-4520-B23A-04C3AD6DABE3}',{$ENDIF}100);
224 //format;
225 end;
GDBObjEllipse.GetObjTypenull226 function GDBObjEllipse.GetObjType;
227 begin
228 result:=GDBEllipseID;
229 end;
230 procedure GDBObjEllipse.CalcObjMatrix;
231 var m1:DMatrix4D;
232 v:GDBvertex4D;
233 begin
234 inherited CalcObjMatrix;
235 m1:=ONEMATRIX;
236 m1[0, 0] := {ratio*}onevertexlength(majoraxis);
237 m1[1, 1] := ratio*onevertexlength(majoraxis);
238 m1[2, 2] := {ratio*onevertexlength(majoraxis)}1;
239 objmatrix:=matrixmultiply(m1,objmatrix);
240
241 pgdbvertex(@v)^:=local.p_insert;
242 v.z:=0;
243 v.w:=1;
244 m1:=objMatrix;
245 MatrixInvert(m1);
246 v:=VectorTransform(v,m1);
247 end;
248 procedure GDBObjEllipse.FormatEntity(var drawing:TDrawingDef;var DC:TDrawContext);
249 var
250 v:GDBvertex4D;
251 begin
252 if self.Ratio<=1 then
253 rr:=uzegeometry.oneVertexlength(majoraxis)
254 else
255 rr:=uzegeometry.oneVertexlength(majoraxis)*ratio;
256
257 calcObjMatrix;
258 angle := endangle - startangle;
259 if angle < 0 then angle := 2 * pi + angle;
260 length := abs(angle){*pi/180} * rr;//---------------------------------------------------------------
261 v.x:=cos(startangle{*pi/180});
262 v.y:=sin(startangle{*pi/180});
263 v.z:=0;
264 v.w:=1;
265 v:=VectorTransform(v,objMatrix);
266 q0:=pgdbvertex(@v)^;
267 v.x:=cos(startangle+angle{*pi/180}/2);
268 v.y:=sin(startangle+angle{*pi/180}/2);
269 v.z:=0;
270 v.w:=1;
271 v:=VectorTransform(v,objMatrix);
272 q1:=pgdbvertex(@v)^;
273 v.x:=cos(endangle{*pi/180});
274 v.y:=sin(endangle{*pi/180});
275 v.z:=0;
276 v.w:=1;
277 v:=VectorTransform(v,objMatrix);
278 q2:=pgdbvertex(@v)^;
279
280 calcbb(dc);
281 createpoint;
282 end;
283 procedure GDBObjEllipse.getoutbound;
284 var //tv,tv2:GDBVertex;
285 t,b,l,rrr,n,f:GDBDouble;
286 i:integer;
287 begin
288 outbound[0]:=VectorTransform3d(CreateVertex(-1,1,0),objMatrix);
289 outbound[1]:=VectorTransform3d(CreateVertex(1,1,0),objMatrix);
290 outbound[2]:=VectorTransform3d(CreateVertex(1,-1,0),objMatrix);
291 outbound[3]:=VectorTransform3d(CreateVertex(-1,-1,0),objMatrix);
292
293 {outbound[0]:=VectorTransform3d(CreateVertex(cos(startangle),sin(startangle),0),objMatrix);
294 outbound[1]:=VectorTransform3d(CreateVertex(cos(endangle),sin(endangle),0),objMatrix);
295 tv:=vertexsub(pgdbvertex(@outbound[1])^,pgdbvertex(@outbound[0])^);
296 t:=tv.x;
297 tv.x:=tv.y;
298 tv.y:=t;
299 outbound[2]:=vertexadd(outbound[1],tv);
300 outbound[3]:=vertexadd(outbound[0],tv);}
301
302
303 l:=outbound[0].x;
304 rrr:=outbound[0].x;
305 t:=outbound[0].y;
306 b:=outbound[0].y;
307 n:=outbound[0].z;
308 f:=outbound[0].z;
309 for i:=1 to 3 do
310 begin
311 if outbound[i].x<l then
312 l:=outbound[i].x;
313 if outbound[i].x>rrr then
314 rrr:=outbound[i].x;
315 if outbound[i].y<b then
316 b:=outbound[i].y;
317 if outbound[i].y>t then
318 t:=outbound[i].y;
319 if outbound[i].z<n then
320 n:=outbound[i].z;
321 if outbound[i].z>f then
322 f:=outbound[i].z;
323 end;
324
325 vp.BoundingBox.LBN:=CreateVertex(l,B,n);
326 vp.BoundingBox.RTF:=CreateVertex(rrr,T,f);
327 if PProjoutbound=nil then
328 begin
329 GDBGetMem({$IFDEF DEBUGBUILD}'{B9B13A5B-467C-4E8A-B4BD-6F54713EBC0D}',{$ENDIF}GDBPointer(PProjoutbound),sizeof(GDBOOutbound2DIArray));
330 PProjoutbound^.init({$IFDEF DEBUGBUILD}'{2D0D05D3-F10A-473F-88FC-D5FB9BD7B539}',{$ENDIF}4);
331 end;
332 end;
333 procedure GDBObjEllipse.createpoint;
334 var
335 //psymbol: PGDBByte;
336 i{, j, k}: GDBInteger;
337 //len: GDBWord;
338 //matr{,m1}: DMatrix4D;
339 v:GDBvertex;
340 pv:GDBVertex;
341 begin
342 {oglsm.myglpushmatrix;
343 glscaledf(r, r, 1);
344 gltranslatef(p_insert.x / r, p_insert.y / r, p_insert.z);
345 angle := endangle - startangle;
346 if angle < 0 then angle := 2 * pi + angle;
347 myglbegin(GL_line_strip);
348 glVertex3d(cos(startangle), sin(startangle), 0);
349 for i := 1 to arccount do
350 begin
351 glVertex3d(cos(startangle + i / arccount * angle), sin(startangle + i / arccount * angle), 0);
352 end;
353 myglend;
354 oglsm.myglpopmatrix;}
355 angle := endangle - startangle;
356 if angle < 0 then angle := 2 * pi + angle;
357
358 Vertex3D_in_WCS_Array.clear;
359 {if ppoint<>nil then
360 begin
361 ppoint^.done;
362 GDBFreeMem(ppoint);
363 end;
364 GDBGetMem(PPoint,sizeof(GDBPoint2DArray));
365 PPoint^.init(lod+1);}
366 //matr:=objMatrix;
367 v.x:=cos(startangle);
368 v.y:=sin(startangle);
369 v.z:=0;
370 pv:=VectorTransform3D(v,objmatrix);
371 Vertex3D_in_WCS_Array.PushBackData(pv);
372
373 lod:=100; { TODO : А кто лод считать будет? }
374
375 for i:=1 to lod do
376 begin
377 v.x:=cos(startangle+i / lod * angle);
378 v.y:=sin(startangle+i / lod * angle);
379 v.z:=0;
380 pv:=VectorTransform3D(v,objmatrix);
381 Vertex3D_in_WCS_Array.PushBackData(pv);
382 end;
383 Vertex3D_in_WCS_Array.Shrink;
384 end;
385 procedure GDBObjEllipse.Renderfeedback;
386 var //pm:DMatrix4D;
387 tv:GDBvertex;
388 d:GDBDouble;
389 begin
390 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(Local.p_insert,ProjP_insert);
391 pprojoutbound^.clear;
392 //pm:=gdb.GetCurrentDWG.pcamera^.modelMatrix;
393 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(outbound[0],tv);
394 pprojoutbound^.PushBackIfNotLastWithCompareProc(ToVertex2DI(tv),EqualVertex2DI);
395 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(outbound[1],tv);
396 pprojoutbound^.PushBackIfNotLastWithCompareProc(ToVertex2DI(tv),EqualVertex2DI);
397 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(outbound[2],tv);
398 pprojoutbound^.PushBackIfNotLastWithCompareProc(ToVertex2DI(tv),EqualVertex2DI);
399 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(outbound[3],tv);
400 pprojoutbound^.PushBackIfNotLastOrFirstWithCompareProc(ToVertex2DI(tv),EqualVertex2DI);
401 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(q0,pq0);
402 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(q1,pq1);
403 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(q2,pq2);
404 if pprojoutbound^.count<4 then
405 begin
406 lod:=4;
407 //projectpoint;
408 end
409 else
410 begin
411 d:=pprojoutbound^.perimetr;
412 d:=(angle/(2*pi))*(d/10);
413 if d>255 then d:=255;
414 if d<10 then d:=10;
415 if lod<>round(d) then
416 begin
417 lod:=round(d);
418 createpoint;
419 end;
420 projectpoint;
421 end;
422 end;
423 procedure GDBObjEllipse.DrawGeometry;
424 //var
425 // i: GDBInteger;
426 begin
427
428 DC.drawer.DrawClosedContour3DInModelSpace(Vertex3D_in_WCS_Array,DC.DrawingContext.matrixs);
429 //Vertex3D_in_WCS_Array.drawgeometry;
430
431 inherited;
432
433 end;
434 procedure GDBObjEllipse.projectpoint;
435 //var pm:DMatrix4D;
436 // tv:GDBvertex;
437 // tpv:GDBPolyVertex2D;
438 // ptpv:PGDBPolyVertex2D;
439 // i:GDBInteger;
440 begin
441
442 end;
443 procedure GDBObjEllipse.SaveToDXF;
444 begin
445 SaveToDXFObjPrefix(outhandle,'ELLIPSE','AcDbEllipse',IODXFContext);
446 dxfvertexout(outhandle,10,Local.p_insert);
447 dxfvertexout(outhandle,11,majoraxis);
448 SaveToDXFObjPostfix(outhandle);
449
450 //dxfGDBStringout(outhandle,100,'AcDbEllipse');
451 //WriteString_EOL(outhandle, '100');
452 //WriteString_EOL(outhandle, 'AcDbArc');
453 dxfGDBDoubleout(outhandle,40,ratio{ * 180 / pi});
454 dxfGDBDoubleout(outhandle,41,startangle{ * 180 / pi});
455 dxfGDBDoubleout(outhandle,42,endangle{ * 180 / pi});
456 end;
457 procedure GDBObjEllipse.LoadFromDXF;
458 var //s: GDBString;
459 byt{, code}: GDBInteger;
460 begin
461 //initnul;
462 byt:=readmystrtoint(f);
463 while byt <> 0 do
464 begin
465 if not LoadFromDXFObjShared(f,byt,ptu,drawing) then
466 if not dxfvertexload(f,10,byt,Local.P_insert) then
467 if not dxfvertexload(f,11,byt,MajorAxis) then
468 if not dxfGDBDoubleload(f,40,byt,ratio) then
469 if not dxfGDBDoubleload(f,41,byt,startangle) then
470 if not dxfGDBDoubleload(f,42,byt,endangle) then {s := }f.readgdbstring;
471 byt:=readmystrtoint(f);
472 end;
473 startangle := startangle{ * pi / 180};
474 endangle := endangle{ * pi / 180};
475 PProjoutbound:=nil;
476 //format;
477 end;
GDBObjEllipse.onmousenull478 function GDBObjEllipse.onmouse;
479 var i:GDBInteger;
480 begin
481 for i:=0 to 5 do
482 begin
483 if(mf[i][0] * P_insert_in_WCS.x + mf[i][1] * P_insert_in_WCS.y + mf[i][2] * P_insert_in_WCS.z + mf[i][3]+RR < 0 )
484 then
485 begin
486 result:=false;
487 //system.break;
488 exit;
489 end;
490 end;
491 result:=Vertex3D_in_WCS_Array.onmouse(mf,false);
492 end;
493 procedure GDBObjEllipse.remaponecontrolpoint(pdesc:pcontrolpointdesc);
494 begin
495 case pdesc^.pointtype of
496 os_begin:begin
497 pdesc.worldcoord:=q0;
498 pdesc.dispcoord.x:=round(Pq0.x);
499 pdesc.dispcoord.y:=round(Pq0.y);
500 end;
501 os_midle:begin
502 pdesc.worldcoord:=q1;
503 pdesc.dispcoord.x:=round(Pq1.x);
504 pdesc.dispcoord.y:=round(Pq1.y);
505 end;
506 os_end:begin
507 pdesc.worldcoord:=q2;
508 pdesc.dispcoord.x:=round(Pq2.x);
509 pdesc.dispcoord.y:=round(Pq2.y);
510 end;
511 end;
512 end;
513 procedure GDBObjEllipse.addcontrolpoints(tdesc:GDBPointer);
514 var pdesc:controlpointdesc;
515 begin
516 PSelectedObjDesc(tdesc)^.pcontrolpoint^.init({$IFDEF DEBUGBUILD}'{8E7285C9-05AD-4D34-9E9D-479D394B2AAF}',{$ENDIF}3);
517 pdesc.selected:=false;
518 pdesc.pobject:=nil;
519
520 pdesc.pointtype:=os_begin;
521 pdesc.attr:=[CPA_Strech];
522 pdesc.worldcoord:=q0;
523 {pdesc.dispcoord.x:=round(Pq0.x);
524 pdesc.dispcoord.y:=round(Pq0.y);}
525 PSelectedObjDesc(tdesc)^.pcontrolpoint^.PushBackData(pdesc);
526
527 pdesc.pointtype:=os_midle;
528 pdesc.attr:=[];
529 pdesc.worldcoord:=q1;
530 {pdesc.dispcoord.x:=round(Pq1.x);
531 pdesc.dispcoord.y:=round(Pq1.y);}
532 PSelectedObjDesc(tdesc)^.pcontrolpoint^.PushBackData(pdesc);
533
534 pdesc.pointtype:=os_end;
535 pdesc.attr:=[CPA_Strech];
536 pdesc.worldcoord:=q1;
537 {pdesc.dispcoord.x:=round(Pq2.x);
538 pdesc.dispcoord.y:=round(Pq2.y);}
539 PSelectedObjDesc(tdesc)^.pcontrolpoint^.PushBackData(pdesc);
540 end;
GDBObjEllipse.getsnapnull541 function GDBObjEllipse.getsnap;
542 //var t,d,e:GDBDouble;
543 // tv,n,v:gdbvertex;
544 begin
545 if onlygetsnapcount=3 then
546 begin
547 result:=false;
548 exit;
549 end;
550 result:=true;
551 case onlygetsnapcount of
552 0:begin
553 if (SnapMode and osm_endpoint)<>0
554 then
555 begin
556 osp.worldcoord:=q0;
557 pgdbvertex2d(@osp.dispcoord)^:=pgdbvertex2d(@pq0)^;
558 osp.ostype:=os_begin;
559 end
560 else osp.ostype:=os_none;
561 end;
562 1:begin
563 if (SnapMode and osm_midpoint)<>0
564 then
565 begin
566 osp.worldcoord:=q1;
567 pgdbvertex2d(@osp.dispcoord)^:=pgdbvertex2d(@pq1)^;
568 osp.ostype:=os_midle;
569 end
570 else osp.ostype:=os_none;
571 end;
572 2:begin
573 if (SnapMode and osm_endpoint)<>0
574 then
575 begin
576 osp.worldcoord:=q2;
577 pgdbvertex2d(@osp.dispcoord)^:=pgdbvertex2d(@pq2)^;
578 osp.ostype:=os_end;
579 end
580 else osp.ostype:=os_none;
581 end;
582 end;
583 inc(onlygetsnapcount);
584 end;
GDBObjEllipse.beforertmodifynull585 function GDBObjEllipse.beforertmodify;
586 begin
587 GDBGetMem({$IFDEF DEBUGBUILD}'{77AF2FA4-2EDC-46CD-A813-6E34E2AC91A5}',{$ENDIF}result,sizeof(tellipsertmodify));
588 tellipsertmodify(result^).p1.x:=q0.x;
589 tellipsertmodify(result^).p1.y:=q0.y;
590 tellipsertmodify(result^).p2.x:=q1.x;
591 tellipsertmodify(result^).p2.y:=q1.y;
592 tellipsertmodify(result^).p3.x:=q2.x;
593 tellipsertmodify(result^).p3.y:=q2.y;
594 end;
GDBObjEllipse.IsRTNeedModifynull595 function GDBObjEllipse.IsRTNeedModify(const Point:PControlPointDesc; p:GDBPointer):Boolean;
596 begin
597 result:=true;
598 end;
599 procedure GDBObjEllipse.rtmodifyonepoint(const rtmod:TRTModifyData);
600 var a,b,c,d,e,f,g,p_x,p_y,rrr:GDBDouble;
601 tv:gdbvertex2d;
602 ptdata:tellipsertmodify;
603 begin
604 ptdata.p1.x:=q0.x;
605 ptdata.p1.y:=q0.y;
606 ptdata.p2.x:=q1.x;
607 ptdata.p2.y:=q1.y;
608 ptdata.p3.x:=q2.x;
609 ptdata.p3.y:=q2.y;
610
611 case rtmod.point.pointtype of
612 os_begin:begin
613 ptdata.p1.x:=q0.x+rtmod.dist.x;
614 ptdata.p1.y:=q0.y+rtmod.dist.y;
615 end;
616 os_midle:begin
617 ptdata.p2.x:=q1.x+rtmod.dist.x;
618 ptdata.p2.y:=q1.y+rtmod.dist.y;
619 end;
620 os_end:begin
621 ptdata.p3.x:=q2.x+rtmod.dist.x;
622 ptdata.p3.y:=q2.y+rtmod.dist.y;
623 end;
624 end;
625 A:= ptdata.p2.x - ptdata.p1.x;
626 B:= ptdata.p2.y - ptdata.p1.y;
627 C:= ptdata.p3.x - ptdata.p1.x;
628 D:= ptdata.p3.y - ptdata.p1.y;
629
630 E:= A*(ptdata.p1.x + ptdata.p2.x) + B*(ptdata.p1.y + ptdata.p2.y);
631 F:= C*(ptdata.p1.x + ptdata.p3.x) + D*(ptdata.p1.y + ptdata.p3.y);
632
633 G:= 2*(A*(ptdata.p3.y - ptdata.p2.y)-B*(ptdata.p3.x - ptdata.p2.x));
634 if abs(g)>eps then
635 begin
636 p_x:= (D*E - B*F) / G;
637 p_y:= (A*F - C*E) / G;
638 rrr:= sqrt(sqr(ptdata.p1.x - p_x) + sqr(ptdata.p1.y - p_y));
639 rr:=rrr;
640 Local.p_insert.x:=p_x;
641 Local.p_insert.y:=p_y;
642 Local.p_insert.z:=0;
643 tv.x:=p_x;
644 tv.y:=p_y;
645 startangle:=vertexangle(tv,ptdata.p1);
646 endangle:=vertexangle(tv,ptdata.p3);
647 if startangle>endangle then
648 begin
649 rrr:=startangle;
650 startangle:=endangle;
651 endangle:=rrr
652 end;
653 rrr:=vertexangle(tv,ptdata.p2);
654 if (rrr>startangle) and (rrr<endangle) then
655 begin
656 end
657 else
658 begin
659 rrr:=startangle;
660 startangle:=endangle;
661 endangle:=rrr
662 end;
663 //format;
664 //renderfeedback(gdb.GetCurrentDWG.pcamera^.POSCOUNT,gdb.GetCurrentDWG.pcamera^,nil);
665 end;
666
667 end;
GDBObjEllipse.Clonenull668 function GDBObjEllipse.Clone;
669 var tvo: PGDBObjEllipse;
670 begin
671 GDBGetMem({$IFDEF DEBUGBUILD}'{368BA81A-219B-4DE9-A8E0-64EE16001126}',{$ENDIF}GDBPointer(tvo), sizeof(GDBObjEllipse));
672 tvo^.init(bp.ListPos.owner,vp.Layer, vp.LineWeight, Local.p_insert, {r,}startangle,endangle,majoraxis);
673 CopyVPto(tvo^);
674 //tvo^.vp.ID:=GDBEllipseID;
675 tvo^.Local:=local;
676 tvo^.RR:=RR;
677 tvo^.MajorAxis:=MajorAxis;
678 tvo^.Ratio:=Ratio;
679
680 //tvo^.format;
681 result := tvo;
682 end;
683 procedure GDBObjEllipse.rtsave;
684 begin
685 PGDBObjEllipse(refp)^.Local.p_insert := Local.p_insert;
686 PGDBObjEllipse(refp)^.startangle := startangle;
687 PGDBObjEllipse(refp)^.endangle := endangle;
688 PGDBObjEllipse(refp)^.RR:=RR;
689 PGDBObjEllipse(refp)^.MajorAxis:=MajorAxis;
690 PGDBObjEllipse(refp)^.Ratio:=Ratio;
691 //PGDBObjEllipse(refp)^.format;
692 //PGDBObjEllipse(refp)^.renderfeedback(gdb.GetCurrentDWG.pcamera^.POSCOUNT,gdb.GetCurrentDWG.pcamera^,nil);
693 end;
AllocEllipsenull694 function AllocEllipse:PGDBObjEllipse;
695 begin
696 GDBGetMem({$IFDEF DEBUGBUILD}'{AllocEllipse}',{$ENDIF}result,sizeof(GDBObjEllipse));
697 end;
AllocAndInitEllipsenull698 function AllocAndInitEllipse(owner:PGDBObjGenericWithSubordinated):PGDBObjEllipse;
699 begin
700 result:=AllocEllipse;
701 result.initnul{(owner)};
702 result.bp.ListPos.Owner:=owner;
703 end;
GDBObjEllipse.CreateInstancenull704 function GDBObjEllipse.CreateInstance:PGDBObjEllipse;
705 begin
706 result:=AllocAndInitEllipse(nil);
707 end;
708 begin
709 RegisterDXFEntity(GDBEllipseID,'ELLIPSE','Ellipse',@AllocEllipse,@AllocAndInitEllipse);
710 end.
711