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
19 unit uzeentline;
20 {$INCLUDE def.inc}
21
22 interface
23 uses LCLProc,uzeentityfactory,uzgldrawcontext,uzedrawingdef,uzecamera,
24 gzctnrvectorpobjects,uzestyleslayers,uzbtypesbase,uzeentsubordinated,
25 UGDBSelectedObjArray,uzeent3d,uzeentity,UGDBOpenArrayOfByte,uzbtypes,uzeconsts,
26 uzbgeomtypes,uzglviewareadata,uzegeometry,uzeffdxfsupport,uzbmemman;
27 type
28 {REGISTEROBJECTTYPE GDBObjLine}
29 {Export+}
30 PGDBObjLine=^GDBObjLine;
31 GDBObjLine={$IFNDEF DELPHI}packed{$ENDIF} object(GDBObj3d)
32 CoordInOCS:GDBLineProp;(*'Coordinates OCS'*)(*saved_to_shd*)
33 CoordInWCS:GDBLineProp;(*'Coordinates WCS'*)(*hidden_in_objinsp*)
34 PProjPoint:PGDBLineProj;(*'Coordinates DCS'*)(*hidden_in_objinsp*)
35
36 constructor init(own:GDBPointer;layeraddres:PGDBLayerProp;LW:GDBSmallint;p1,p2:GDBvertex);
37 constructor initnul(owner:PGDBObjGenericWithSubordinated);
38 procedure LoadFromDXF(var f: GDBOpenArrayOfByte;ptu:PExtensionData;var drawing:TDrawingDef);virtual;
39
40 procedure SaveToDXF(var outhandle:{GDBInteger}GDBOpenArrayOfByte;var drawing:TDrawingDef;var IODXFContext:TIODXFContext);virtual;
41 procedure FormatEntity(var drawing:TDrawingDef;var DC:TDrawContext);virtual;
42 procedure CalcGeometry;virtual;
43 procedure DrawGeometry(lw:GDBInteger;var DC:TDrawContext{infrustumactualy:TActulity;subrender:GDBInteger});virtual;
44 procedure RenderFeedback(pcount:TActulity;var camera:GDBObjCamera; ProjectProc:GDBProjectProc;var DC:TDrawContext);virtual;
Clonenull45 function Clone(own:GDBPointer):PGDBObjEntity;virtual;
46 procedure rtedit(refp:GDBPointer;mode:GDBFloat;dist,wc:gdbvertex);virtual;
47 procedure rtsave(refp:GDBPointer);virtual;
48 procedure TransformAt(p:PGDBObjEntity;t_matrix:PDMatrix4D);virtual;
onmousenull49 function onmouse(var popa:TZctnrVectorPGDBaseObjects;const MF:ClipArray;InSubEntry:GDBBoolean):GDBBoolean;virtual;
onpointnull50 function onpoint(var objects:TZctnrVectorPGDBaseObjects;const point:GDBVertex):GDBBoolean;virtual;
51 //procedure feedbackinrect;virtual;
InRectnull52 //function InRect:TInRect;virtual;
53 function getsnap(var osp:os_record; var pdata:GDBPointer; const param:OGLWndtype; ProjectProc:GDBProjectProc;SnapMode:TGDBOSMode):GDBBoolean;virtual;
getintersectnull54 function getintersect(var osp:os_record;pobj:PGDBObjEntity; const param:OGLWndtype; ProjectProc:GDBProjectProc;SnapMode:TGDBOSMode):GDBBoolean;virtual;
55 destructor done;virtual;
56 procedure addcontrolpoints(tdesc:GDBPointer);virtual;
beforertmodifynull57 function beforertmodify:GDBPointer;virtual;
58 procedure clearrtmodify(p:GDBPointer);virtual;
59 procedure rtmodifyonepoint(const rtmod:TRTModifyData);virtual;
IsRTNeedModifynull60 function IsRTNeedModify(const Point:PControlPointDesc; p:GDBPointer):Boolean;virtual;
61 procedure remaponecontrolpoint(pdesc:pcontrolpointdesc);virtual;
62 procedure transform(const t_matrix:DMatrix4D);virtual;
jointolinenull63 function jointoline(pl:pgdbobjline;var drawing:TDrawingDef):GDBBoolean;virtual;
64
ObjToGDBStringnull65 function ObjToGDBString(prefix,sufix:GDBString):GDBString;virtual;
GetObjTypeNamenull66 function GetObjTypeName:GDBString;virtual;
GetCenterPointnull67 function GetCenterPoint:GDBVertex;virtual;
68 procedure getoutbound(var DC:TDrawContext);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;
71
IsIntersect_Linenull72 function IsIntersect_Line(lbegin,lend:gdbvertex):Intercept3DProp;virtual;
73 procedure AddOnTrackAxis(var posr:os_record;const processaxis:taddotrac);virtual;
GetTangentInPointnull74 function GetTangentInPoint(point:GDBVertex):GDBVertex;virtual;
75
CreateInstancenull76 class function CreateInstance:PGDBObjLine;static;
GetObjTypenull77 function GetObjType:TObjID;virtual;
78 end;
79 {Export-}
80 ptlinertmodify=^tlinertmodify;
81 tlinertmodify=record
82 lbegin,lmidle,lend:GDBBoolean;
83 end;
AllocAndInitLinenull84 function AllocAndInitLine(owner:PGDBObjGenericWithSubordinated):PGDBObjLine;
85 implementation
86 //uses log;
GDBObjLine.GetTangentInPointnull87 function GDBObjLine.GetTangentInPoint(point:GDBVertex):GDBVertex;
88 begin
89 result:=normalizevertex(VertexSub(CoordInWCS.lEnd,CoordInWCS.lBegin));
90 end;
91 procedure GDBObjLine.AddOnTrackAxis(var posr:os_record;const processaxis:taddotrac);
92 var tv,dir:gdbvertex;
93 begin
94 dir:=VertexSub(CoordInWCS.lEnd,CoordInWCS.lBegin);
95 processaxis(posr,dir);
96 //posr.arrayworldaxis.Add(@dir);
97 tv:=uzegeometry.vectordot(dir,zwcs);
98 processaxis(posr,tv);
99 //posr.arrayworldaxis.Add(@tv);
100 end;
GDBObjLine.IsIntersect_Linenull101 function GDBObjLine.IsIntersect_Line(lbegin,lend:gdbvertex):Intercept3DProp;
102 begin
103 result:=intercept3d(lbegin,lend,CoordInWCS.lBegin,CoordInWCS.lEnd);
104 end;
105 procedure GDBObjLine.getoutbound;
106 //var //tv,tv2:GDBVertex4D;
107 //t,b,l,r,n,f:GDBDouble;
108 begin
109 vp.BoundingBox:=CreateBBFrom2Point(CoordInWCS.lBegin,CoordInWCS.lEnd);
110 end;
GDBObjLine.GetCenterPointnull111 function GDBObjLine.GetCenterPoint;
112 begin
113 result:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 0.5);
114 end;
GDBObjLine.GetObjTypeNamenull115 function GDBObjLine.GetObjTypeName;
116 begin
117 result:=ObjN_GDBObjLine;
118 end;
GDBObjLine.jointolinenull119 function GDBObjLine.jointoline(pl:pgdbobjline;var drawing:TDrawingDef):GDBBoolean;
onlinenull120 function online(w,u:gdbvertex):GDBBoolean;
121 var ww:GDBDouble;
122 l:GDBDouble;
123 begin
124 ww:=scalardot(w,u);
125 l:=SqrOneVertexlength(VertexSub(w,VertexMulOnSc(u,ww)));
126 if eps>l then
127 result:=true
128 else
129 result:=false;
130 end;
131 var t1,t2,a1,a2:GDBDouble;
132 q:GDBBoolean;
133 w,u,dir:gdbvertex;
134 dc:TDrawContext;
135 begin
136 result:=false;
137 if Vertexlength(CoordInWCS.lbegin, CoordInWCS.lend)<Vertexlength(pl^.CoordInWCS.lbegin,pl^.CoordInWCS.lend) then
138 begin
139 result:=pl^.jointoline(@self,drawing);
140 exit;
141 end;
142 dir:=VertexSub(CoordInWCS.lEnd,CoordInWCS.lBegin);
143 u:=NormalizeVertex(dir);
144 w:=VertexSub(pl.coordinwcs.lbegin,coordinwcs.lbegin);
145 t1:=(scalardot(w,dir))/SqrOneVertexlength(dir);
146 q:=online(w,u);
147 w:=VertexSub(pl.coordinwcs.lend,coordinwcs.lbegin);
148 t2:=(scalardot(w,dir))/SqrOneVertexlength(dir);
149 q:=q and online(w,u);
150 if not q then exit;
151 a1:=0;
152 a2:=1;
153 if t1<a1 then a1:=t1;
154 if t2<a1 then a1:=t2;
155 if t1>a2 then a2:=t1;
156 if t2>a2 then a2:=t2;
157 self.CoordInOCS.lend:=VertexDmorph(self.CoordInOCS.lbegin,dir,a2);
158 self.CoordInOCS.lbegin:=VertexDmorph(self.CoordInOCS.lbegin,dir,a1);
159 self.CoordInWCS.lend:=VertexDmorph(self.CoordInWCS.lbegin,dir,a2);
160 self.CoordInWCS.lbegin:=VertexDmorph(self.CoordInWCS.lbegin,dir,a1);
161 dc:=drawing.CreateDrawingRC;
162 FormatEntity(drawing,dc);
163 pl^.YouDeleted(drawing);
164 result:=true;
165 end;
GDBObjLine.ObjToGDBStringnull166 function GDBObjLine.ObjToGDBString(prefix,sufix:GDBString):GDBString;
167 begin
168 result:=prefix+inherited ObjToGDBString('GDBObjLine (addr:',')')+sufix;
169 end;
170 constructor GDBObjLine.initnul;
171 begin
172 inherited initnul(owner);
173 bp.ListPos.Owner:=owner;
174 //vp.ID := GDBlineID;
175 CoordInOCS.lBegin := NulVertex;
176 CoordInOCS.lEnd := NulVertex;
177 PProjPoint:=nil;
178 end;
179 constructor GDBObjLine.init;
180 begin
181 inherited init(own,layeraddres, lw);
182 //vp.ID := GDBlineID;
183 CoordInOCS.lBegin := p1;
184 CoordInOCS.lEnd := p2;
185 PProjPoint:=nil;
186 //format;
187 end;
GDBObjLine.GetObjTypenull188 function GDBObjLine.GetObjType;
189 begin
190 result:=GDBlineID;
191 end;
192 procedure GDBObjLine.LoadFromDXF;
193 var //s: GDBString;
194 byt: GDBInteger;
195 begin
196 byt:=readmystrtoint(f);
197 while byt <> 0 do
198 begin
199 if not LoadFromDXFObjShared(f,byt,ptu,drawing) then
200 if not dxfvertexload(f,10,byt,CoordInOCS.lBegin) then
201 if not dxfvertexload(f,11,byt,CoordInOCS.lEnd) then {s := }f.readGDBSTRING;
202 byt:=readmystrtoint(f);
203 end;
204 end;
205 destructor GDBObjLine.done;
206 begin
207 if PProjPoint<>nil then
208 GDBFreeMem(GDBPointer(PProjPoint));
209 inherited done;
210 end;
211 procedure GDBObjLine.CalcGeometry;
212 var m:DMatrix4D;
213 begin
214 if bp.ListPos.owner<>nil then
215 begin
216 if bp.ListPos.owner^.GetHandle=H_Root then
217 begin
218 CoordInWCS.lbegin:=CoordInOCS.lbegin;
219 CoordInWCS.lend:=CoordInOCS.lend;
220 end
221 else
222 begin
223 m:=bp.ListPos.owner^.GetMatrix^;
224 CoordInWCS.lbegin:=VectorTransform3D(CoordInOCS.lbegin,m);
225 CoordInWCS.lend:=VectorTransform3D(CoordInOCS.lend,m);
226 end;
227 end
228 else
229 begin
230 CoordInWCS.lbegin:=CoordInOCS.lbegin;
231 CoordInWCS.lend:=CoordInOCS.lend;
232 end;
233 end;
234
235 procedure GDBObjLine.FormatEntity(var drawing:TDrawingDef;var DC:TDrawContext);
236 begin
237 calcgeometry;
238 calcbb(dc);
239
240 Representation.Clear;
241 Representation.DrawLineWithLT(dc,CoordInWCS.lBegin,CoordInWCS.lEnd,vp);
242 end;
GDBObjLine.CalcInFrustumnull243 function GDBObjLine.CalcInFrustum;
244 var i:GDBInteger;
245 begin
246 if CalcAABBInFrustum(vp.BoundingBox,frustum)<>IREmpty then
247 result:=true
248 else
249 result:=false;
250 exit;
251 result:=true;
252 for i:=0 to 5 do
253 begin
254 if(frustum[i][0] * CoordInWCS.lbegin.x + frustum[i][1] * CoordInWCS.lbegin.y + frustum[i][2] * CoordInWCS.lbegin.z + frustum[i][3] < 0 )
255 and(frustum[i][0] * CoordInWCS.lend.x + frustum[i][1] * CoordInWCS.lend.y + frustum[i][2] * CoordInWCS.lend.z + frustum[i][3] < 0 )
256 then
257 begin
258 result:=false;
259 system.break;
260 end;
261 end;
262 end;
GDBObjLine.CalcTrueInFrustumnull263 function GDBObjLine.CalcTrueInFrustum;
264 begin
265 result:=Representation.CalcTrueInFrustum(frustum,true);
266 end;
GDBObjLine.onpointnull267 function GDBObjLine.onpoint(var objects:TZctnrVectorPGDBaseObjects;const point:GDBVertex):GDBBoolean;
268 begin
269 if {distance2piece}SQRdist_Point_to_Segment(point,self.CoordInWCS.lBegin,self.CoordInWCS.lEnd)<bigeps then
270 begin
271 result:=true;
272 objects.PushBackData(@self);
273 end
274 else
275 result:=false;
276 end;
277
GDBObjLine.onmousenull278 function GDBObjLine.onmouse;
279 begin
280 if Representation.CalcTrueInFrustum(mf,false)<>IREmpty
281 then
282 result:=true
283 else
284 result:=false;
285 end;
286 procedure GDBObjLine.DrawGeometry;
287 //var
288 // templod:gdbdouble;
289 begin
290 if (selected)or(dc.selected) then
291 Representation.DrawNiceGeometry(DC)
292 else
293 begin
294 Representation.DrawGeometry(DC);
295 exit;
296 end;
297 {if vp.LineType<>nil then
298 if vp.LineType.h>0 then
299 begin
300 templod:=(vp.LineType.h*vp.LineTypeScale*SysVar.dwg.DWG_LTScale^)/(dc.zoom);
301 if templod<3 then
302 begin
303 DC.Drawer.DrawLine3DInModelSpace(CoordInWCS.lBegin,CoordInWCS.lEnd,DC.matrixs);
304 end;
305 end;}
306 inherited;
307 {oglsm.myglbegin(GL_points);
308 myglVertex3dV(@CoordInWCS.lBegin);
309 myglVertex3dV(@CoordInWCS.lEnd);
310 oglsm.myglend;}
311 end;
312 procedure GDBObjLine.RenderFeedback;
313 var tv:GDBvertex;
314 // ptv:PGDBvertex;
315 // ptv2d:PGDBvertex2D;
316 // i:GDBInteger;
317 begin
318 //if POGLWnd=nil then exit;
319 {if PProjPoint<>nil then
320 begin
321 GDBFreeMem(GDBPointer(PProjPoint));
322 end;}
323 if PProjPoint=nil then GDBGetMem({$IFDEF DEBUGBUILD}'{BC97B497-84C4-4E1D-9A61-26CA379F29A7}',{$ENDIF}GDBPointer(pprojpoint),sizeof(GDBLineProj));
324
325 ProjectProc(CoordInWCS.lbegin,tv);
326 pprojpoint^[0]:=pGDBvertex2D(@tv)^;
327 ProjectProc(CoordInWCS.lEnd,tv);
328 pprojpoint^[1]:=pGDBvertex2D(@tv)^;
329 ProjectProc(Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 4),tv);
330 pprojpoint^[2]:=pGDBvertex2D(@tv)^;
331 ProjectProc(Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 3),tv);
332 pprojpoint^[3]:=pGDBvertex2D(@tv)^;
333 ProjectProc(Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 2),tv);
334 pprojpoint^[4]:=pGDBvertex2D(@tv)^;
335 ProjectProc(Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 2 / 3),tv);
336 pprojpoint^[5]:=pGDBvertex2D(@tv)^;
337 ProjectProc(Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 3 / 4),tv);
338 pprojpoint^[6]:=pGDBvertex2D(@tv)^;
339
340 {ptv:=@CoordInWCS.lbegin;
341 ptv2d:=@pprojpoint^[0];
342 for i:=0 to 6 do
343 begin iuy
344 myGluProject(ptv^.x,ptv^.y,ptv^.z,@gdb.GetCurrentDWG.pcamera^.modelMatrix,@gdb.GetCurrentDWG.pcamera^.projMatrix,@gdb.GetCurrentDWG.pcamera^.viewport,ptv2d.x,ptv2d.y,tv.z);
345 inc(ptv);
346 inc(ptv2d);
347 end;}
348 //pdx:=PProjPoint[1].x-PProjPoint[0].x;
349 //pdy:=PProjPoint[1].y-PProjPoint[0].y;
350 inherited;
351
352 end;
GDBObjLine.getsnapnull353 function GDBObjLine.getsnap;
354 var t,d,e:GDBDouble;
355 tv,n,v,dir:gdbvertex;
356 begin
357 if onlygetsnapcount=9 then
358 begin
359 result:=false;
360 exit;
361 end;
362 result:=true;
363 dir:=VertexSub(CoordInWCS.lEnd,CoordInWCS.lBegin);
364 case onlygetsnapcount of
365 0:begin
366 if (SnapMode and osm_endpoint)<>0
367 then
368 begin
369 osp.worldcoord:=CoordInWCS.lend;
370 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[1];
371 osp.ostype:=os_end;
372 end
373 else osp.ostype:=os_none;
374 end;
375 1:begin
376 if (SnapMode and osm_4)<>0
377 then
378 begin
379 osp.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 4);
380 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[2];
381 osp.ostype:=os_1_4;
382 end
383 else osp.ostype:=os_none;
384 end;
385 2:begin
386 if (SnapMode and osm_3)<>0
387 then
388 begin
389 osp.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 3);
390 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[3];
391 osp.ostype:=os_1_3;
392 end
393 else osp.ostype:=os_none;
394 end;
395 3:begin
396 if (SnapMode and osm_midpoint)<>0
397 then
398 begin
399 osp.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 2);
400 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[4];
401 osp.ostype:=os_midle;
402 end
403 else osp.ostype:=os_none;
404 end;
405 4:begin
406 if (SnapMode and osm_3)<>0
407 then
408 begin
409 osp.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 2 / 3);
410 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[5];
411 osp.ostype:=os_2_3;
412 end
413 else osp.ostype:=os_none;
414 end;
415 5:begin
416 if (SnapMode and osm_4)<>0
417 then
418 begin
419 osp.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 3 / 4);
420 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[6];
421 osp.ostype:=os_3_4;
422 end
423 else osp.ostype:=os_none;
424 end;
425 6:begin
426 if (SnapMode and osm_endpoint)<>0
427 then
428 begin
429 osp.worldcoord:=CoordInWCS.lbegin;
430 pgdbvertex2d(@osp.dispcoord)^:=pprojpoint^[0];
431 osp.ostype:=os_begin;
432 end
433 else osp.ostype:=os_none;
434 end;
435 7:begin
436 if (SnapMode and osm_perpendicular)<>0
437 then
438 begin
439 tv:=vectordot(dir,{GDB.GetCurrentDWG.OGLwindow1.}param.md.mouseray.dir);
440 t:= -((CoordInWCS.lbegin.x-{GDB.GetCurrentDWG.OGLwindow1.}param.lastpoint.x)*dir.x+(CoordInWCS.lbegin.y-{GDB.GetCurrentDWG.OGLwindow1.}param.lastpoint.y)*dir.y+(CoordInWCS.lbegin.z-{GDB.GetCurrentDWG.OGLwindow1.}param.lastpoint.z)*dir.z)/
441 ({sqr(dir.x)+sqr(dir.y)+sqr(dir.z)}SqrVertexlength(self.CoordInWCS.lBegin,self.CoordInWCS.lEnd){length_2});
442 if (t>=0) and (t<=1)
443 then
444 begin
445 osp.worldcoord.x:=CoordInWCS.lbegin.x+t*dir.x;
446 osp.worldcoord.y:=CoordInWCS.lbegin.y+t*dir.y;
447 osp.worldcoord.z:=CoordInWCS.lbegin.z+t*dir.z;
448 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(osp.worldcoord,tv);
449 osp.dispcoord:=tv;
450 osp.ostype:=os_perpendicular;
451 end
452 else osp.ostype:=os_none;
453 end
454 else osp.ostype:=os_none;
455 end;
456 8:begin
457 if (SnapMode and osm_nearest)<>0
458 then
459 begin
460 tv:=vectordot(dir,{GDB.GetCurrentDWG.OGLwindow1.}param.md.mouseray.dir);
461 n:=vectordot({GDB.GetCurrentDWG.OGLwindow1.}param.md.mouseray.dir,tv);
462 n:=NormalizeVertex(n);
463 v.x:={GDB.GetCurrentDWG.OGLwindow1.}param.md.mouseray.lbegin.x-CoordInWCS.lbegin.x;
464 v.y:={GDB.GetCurrentDWG.OGLwindow1.}param.md.mouseray.lbegin.y-CoordInWCS.lbegin.y;
465 v.z:={GDB.GetCurrentDWG.OGLwindow1.}param.md.mouseray.lbegin.z-CoordInWCS.lbegin.z;
466 d:=scalardot(n,v);
467 e:=scalardot(n,dir);
468 if e<eps then osp.ostype:=os_none
469 else
470 begin
471 if d<eps then osp.ostype:=os_none
472 else
473 begin
474 t:=d/e;
475 if (t>1)or(t<0)then osp.ostype:=os_none
476 else
477 begin
478 osp.worldcoord.x:=CoordInWCS.lbegin.x+t*dir.x;
479 osp.worldcoord.y:=CoordInWCS.lbegin.y+t*dir.y;
480 osp.worldcoord.z:=CoordInWCS.lbegin.z+t*dir.z;
481 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(osp.worldcoord,tv);
482 osp.dispcoord:=tv;
483 osp.ostype:=os_nearest;
484 end;
485 end;
486
487 end;
488 end
489 else osp.ostype:=os_none;
490 end;
491 end;
492 inc(onlygetsnapcount);
493 end;
line2dintercepnull494 function line2dintercep(var x11, y11, x12, y12, x21, y21, x22, y22: GDBDouble; out t1,t2: GDBDouble): GDBBoolean;
495 var
496 d, d1, d2, dx1,dy1,dx2,dy2: GDBDouble;
497 begin
498 t1 := 0;
499 t2 := 0;
500 result := false;
501 dy1:=(y12 - y11);
502 dx2:=(x21 - x22);
503 dy2:=(y21 - y22);
504 dx1:=(x12 - x11);
505 D := dy1{(y12 - y11)} * dx2{(x21 - x22)} - dy2{(y21 - y22)} * dx1{(x12 - x11)};
506 if {(D <> 0)}abs(d)>{bigeps}sqreps then
507 begin
508 D1 := (y12 - y11) * (x21 - x11) - (y21 - y11) * (x12 - x11);
509 D2 := (y21 - y11) * (x21 - x22) - (y21 - y22) * (x21 - x11);
510 t2 := D1 / D;
511 t1 := D2 / D;
512 if ((t1 <= 1) and (t1 >= 0) and (t2 >= 0) and (t2 <= 1)) then
513 begin
514 result := true;
515 end;
516 end;
517 end;
GDBObjLine.getintersectnull518 function GDBObjLine.getintersect;
519 var t1,t2,dist:GDBDouble;
520 tv1,tv2,dir,dir2{,e}:gdbvertex;
521 begin
522 if (onlygetsnapcount=1)or(pobj^.{vp.id}getobjtype<>gdblineid) then
523 begin
524 result:=false;
525 exit;
526 end;
527 result:=true;
528 case onlygetsnapcount of
529 0:begin
530 if ((SnapMode and osm_apparentintersection)<>0)or((SnapMode and osm_intersection)<>0)
531 then
532 begin
533 if not assigned(pgdbobjline(pobj)^.pprojpoint) then
534 begin
535 //pgdbobjline(pobj)^.RenderFeedback(gdb.GetCurrentDWG.pcamera^.POSCOUNT,gdb.GetCurrentDWG.pcamera^,nil);
536 debugln('{E}pobj)^.pprojpoint=nil;//(((((((');
537 osp.ostype:=os_none;
538 exit;
539 end;
540 if line2dintercep(pprojpoint[0].x,pprojpoint[0].y,pprojpoint[1].x,pprojpoint[1].y, pgdbobjline(pobj)^.pprojpoint[0].x,pgdbobjline(pobj)^.pprojpoint[0].y,pgdbobjline(pobj)^.pprojpoint[1].x,pgdbobjline(pobj)^.pprojpoint[1].y, t1,t2)
541 then
542 begin
543 dir:=VertexSub(CoordInWCS.lEnd,CoordInWCS.lBegin);
544 dir2:=VertexSub(pgdbobjline(pobj)^.CoordInWCS.lEnd,pgdbobjline(pobj)^.CoordInWCS.lBegin);
545 tv1.x:=CoordInWCS.lbegin.x+dir.x*t1;
546 tv1.y:=CoordInWCS.lbegin.y+dir.y*t1;
547 tv1.z:=CoordInWCS.lbegin.z+dir.z*t1;
548 tv2.x:=pgdbobjline(pobj)^.CoordInWCS.lbegin.x+dir2.x*t2;
549 tv2.y:=pgdbobjline(pobj)^.CoordInWCS.lbegin.y+dir2.y*t2;
550 tv2.z:=pgdbobjline(pobj)^.CoordInWCS.lbegin.z+dir2.z*t2;
551 dist:=Vertexlength(tv1,tv2);
552 if dist<bigeps
553 then
554 begin
555 if (SnapMode and osm_intersection)<>0
556 then
557 begin
558 osp.worldcoord:=tv1;
559 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(osp.worldcoord,osp.dispcoord);
560 osp.ostype:=os_intersection;
561 end
562 else osp.ostype:=os_none;
563 end
564 else
565 begin
566 if (SnapMode and osm_apparentintersection)<>0
567 then
568 begin
569 osp.worldcoord:=tv1;
570 line2dintercep(pprojpoint[0].x,pprojpoint[0].y,pprojpoint[1].x,pprojpoint[1].y, pgdbobjline(pobj)^.pprojpoint[0].x,pgdbobjline(pobj)^.pprojpoint[0].y,pgdbobjline(pobj)^.pprojpoint[1].x,pgdbobjline(pobj)^.pprojpoint[1].y, t1,t2);
571 {gdb.GetCurrentDWG^.myGluProject2}ProjectProc(osp.worldcoord,osp.dispcoord);
572 osp.ostype:=os_apparentintersection;
573 end
574 else osp.ostype:=os_none;
575 end;
576 end;
577 end
578 else osp.ostype:=os_none;
579 end;
580 end;
581 inc(onlygetsnapcount);
582 end;
GDBObjLine.Clonenull583 function GDBObjLine.Clone;
584 var tvo: PGDBObjLine;
585 begin
586 GDBGetMem({$IFDEF DEBUGBUILD}'{5A1B005F-39F1-431B-B65E-0C532AEFA5D0}-GDBObjLine.Clone',{$ENDIF}GDBPointer(tvo), sizeof(GDBObjLine));
587 tvo^.init(bp.ListPos.owner,vp.Layer, vp.LineWeight, CoordInOCS.lBegin, CoordInOCS.lEnd);
588 CopyVPto(tvo^);
589 tvo^.CoordInOCS.lBegin.y := tvo^.CoordInOCS.lBegin.y;
590 tvo^.bp.ListPos.Owner:=own;
591 //tvo^.format;
592 result := tvo;
593 end;
594 procedure GDBObjLine.SaveToDXF;
595 begin
596 SaveToDXFObjPrefix(outhandle,'LINE','AcDbLine',IODXFContext);
597 dxfvertexout(outhandle,10,CoordInOCS.lbegin);
598 dxfvertexout(outhandle,11,CoordInOCS.lend);
599 end;
600 procedure GDBObjLine.rtedit;
601 begin
602 if mode = os_midle then
603 begin
604 CoordInOCS.lbegin := VertexAdd(pgdbobjline(refp)^.CoordInOCS.lBegin, dist);
605 CoordInOCS.lend := VertexAdd(pgdbobjline(refp)^.CoordInOCS.lend, dist);
606 end
607 else if mode = os_end then
608 begin
609 CoordInOCS.lend := VertexAdd(pgdbobjline(refp)^.CoordInOCS.lend, dist);
610 end
611 else if mode = os_begin then
612 begin
613 CoordInOCS.lbegin := VertexAdd(pgdbobjline(refp)^.CoordInOCS.lBegin, dist);
614 end;
615 //format;
616 end;
617
618 procedure GDBObjLine.rtsave;
619 begin
620 pgdbobjline(refp)^.CoordInOCS.lBegin := CoordInOCS.lbegin;
621 pgdbobjline(refp)^.CoordInOCS.lEnd := CoordInOCS.lend;
622 //pgdbobjline(refp)^.format;
623 end;
624 procedure GDBObjLine.TransformAt;
625 begin
626 CoordInOCS.lbegin:=uzegeometry.VectorTransform3D(pgdbobjline(p)^.CoordInOCS.lBegin,t_matrix^);
627 CoordInOCS.lend:=VectorTransform3D(pgdbobjline(p)^.CoordInOCS.lend,t_matrix^);
628 end;
GDBObjLine.beforertmodifynull629 function GDBObjLine.beforertmodify;
630 begin
631 GDBGetMem({$IFDEF DEBUGBUILD}'{D2E91E60-41CC-45FE-AC5E-CAEC5013C0ED}',{$ENDIF}result,sizeof(tlinertmodify));
632 clearrtmodify(result);
633 end;
634 procedure GDBObjLine.clearrtmodify(p:GDBPointer);
635 begin
636 fillchar(p^,sizeof(tlinertmodify),0);
637 end;
GDBObjLine.IsRTNeedModifynull638 function GDBObjLine.IsRTNeedModify(const Point:PControlPointDesc; p:GDBPointer):Boolean;
639 begin
640 result:=false;
641 case point.pointtype of
642 os_begin:begin
643 if not ptlinertmodify(p)^.lbegin then
644 result:=true;
645 ptlinertmodify(p)^.lbegin:=true;
646 end;
647 os_end:begin
648 if not ptlinertmodify(p)^.lend then
649 result:=true;
650 ptlinertmodify(p)^.lend:=true;
651 end;
652 os_midle:begin
653 if (not ptlinertmodify(p)^.lbegin)
654 and (not ptlinertmodify(p)^.lend) then
655 result:=true;
656 ptlinertmodify(p)^.lbegin:=true;
657 ptlinertmodify(p)^.lend:=true;
658 end;
659 end;
660
661 end;
662
663 procedure GDBObjLine.rtmodifyonepoint(const rtmod:TRTModifyData);
664 var
665 tv,tv2:GDBVERTEX;
666 begin
667 case rtmod.point.pointtype of
668 os_begin:begin
669 CoordInOCS.lbegin:=VertexAdd(rtmod.point.worldcoord, rtmod.dist);
670 end;
671 os_end:begin
672 CoordInOCS.lend:=VertexAdd(rtmod.point.worldcoord, rtmod.dist);
673 end;
674 os_midle:begin
675 tv:=uzegeometry.VertexSub(CoordInOCS.lend,CoordInOCS.lbegin);
676 tv:=uzegeometry.VertexMulOnSc(tv,0.5);
677 tv2:=VertexAdd(rtmod.point.worldcoord, rtmod.dist);
678 CoordInOCS.lbegin:=VertexSub(tv2, tv);
679 CoordInOCS.lend:=VertexAdd(tv2,tv);
680 end;
681 end;
682
683 end;
684 procedure GDBObjLine.remaponecontrolpoint(pdesc:pcontrolpointdesc);
685 begin
686 case pdesc^.pointtype of
687 os_begin:begin
688 pdesc.worldcoord:=CoordInWCS.lbegin;
689 pdesc.dispcoord.x:=round(PProjPoint[0].x);
690 pdesc.dispcoord.y:=round(PProjPoint[0].y);
691 end;
692 os_end:begin
693 pdesc.worldcoord:=CoordInWCS.lend;
694 pdesc.dispcoord.x:=round(PProjPoint[1].x);
695 pdesc.dispcoord.y:=round(PProjPoint[1].y);
696 end;
697 os_midle:begin
698 pdesc.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 2);
699 pdesc.dispcoord.x:=round(PProjPoint[4].x);
700 pdesc.dispcoord.y:=round(PProjPoint[4].y);
701 end;
702 end;
703 end;
704 procedure GDBObjLine.addcontrolpoints(tdesc:GDBPointer);
705 var pdesc:controlpointdesc;
706 begin
707 PSelectedObjDesc(tdesc)^.pcontrolpoint^.init({$IFDEF DEBUGBUILD}'{4CBC9A73-A88D-443B-B925-2F0611D82AB0}',{$ENDIF}3);
708
709 pdesc.selected:=false;
710 pdesc.pobject:=nil;
711
712 //renderfeedback(gdb.GetCurrentDWG.pcamera^.POSCOUNT,gdb.GetCurrentDWG.pcamera^,nil);
713
714 pdesc.pointtype:=os_midle;
715 pdesc.attr:=[];
716 pdesc.worldcoord:=Vertexmorph(CoordInWCS.lbegin, CoordInWCS.lend, 1 / 2);
717 {pdesc.dispcoord.x:=round(PProjPoint[4].x);
718 pdesc.dispcoord.y:=round(PProjPoint[4].y);}
719 PSelectedObjDesc(tdesc)^.pcontrolpoint^.PushBackData(pdesc);
720
721 pdesc.pointtype:=os_begin;
722 pdesc.attr:=[CPA_Strech];
723 pdesc.worldcoord:=CoordInWCS.lbegin;
724 {pdesc.dispcoord.x:=round(PProjPoint[0].x);
725 pdesc.dispcoord.y:=round(PProjPoint[0].y);}
726 PSelectedObjDesc(tdesc)^.pcontrolpoint^.PushBackData(pdesc);
727
728 pdesc.pointtype:=os_end;
729 pdesc.attr:=[CPA_Strech];
730 pdesc.worldcoord:=CoordInWCS.lend;
731 {pdesc.dispcoord.x:=round(PProjPoint[1].x);
732 pdesc.dispcoord.y:=round(PProjPoint[1].y);}
733 PSelectedObjDesc(tdesc)^.pcontrolpoint^.PushBackData(pdesc);
734 end;
735 {function GDBObjLine.InRect;
736 begin
737 result:=IREmpty;
738 if pprojpoint=nil then
739 exit;
740 if pointinquad2d(GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.y, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.y, pprojpoint[0].x,pprojpoint[0].y)
741 and pointinquad2d(GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.y, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.y, pprojpoint[1].x,pprojpoint[1].y)
742 then
743 begin
744 result:=IRFully;
745 end
746 else
747 if
748 intercept2d2(GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.y, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.y, pprojpoint[0].x,pprojpoint[0].y,pprojpoint[1].x,pprojpoint[1].y)
749 or intercept2d2(GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.y, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.y, pprojpoint[0].x,pprojpoint[0].y,pprojpoint[1].x,pprojpoint[1].y)
750 or intercept2d2(GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.y, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.y, pprojpoint[0].x,pprojpoint[0].y,pprojpoint[1].x,pprojpoint[1].y)
751 or intercept2d2(GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame2.y, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.x, GDB.GetCurrentDWG.OGLwindow1.param.seldesc.Frame1.y, pprojpoint[0].x,pprojpoint[0].y,pprojpoint[1].x,pprojpoint[1].y)
752 then
753 begin
754 result:=IRPartially;
755 end
756 end;}
757
758 procedure GDBObjLine.transform;
759 var tv:GDBVertex4D;
760 begin
761 pgdbvertex(@tv)^:=CoordInOCS.lbegin;
762 tv.w:=1;
763 tv:=vectortransform(tv,t_matrix);
764 CoordInOCS.lbegin:=pgdbvertex(@tv)^;
765
766 pgdbvertex(@tv)^:=CoordInOCS.lend;
767 tv.w:=1;
768 tv:=vectortransform(tv,t_matrix);
769 CoordInOCS.lend:=pgdbvertex(@tv)^;
770 end;
AllocLinenull771 function AllocLine:PGDBObjLine;
772 begin
773 GDBGetMem({$IFDEF DEBUGBUILD}'{AllocLine}',{$ENDIF}pointer(result),sizeof(GDBObjLine));
774 end;
AllocAndInitLinenull775 function AllocAndInitLine(owner:PGDBObjGenericWithSubordinated):PGDBObjLine;
776 begin
777 result:=AllocLine;
778 result.initnul(owner);
779 result.bp.ListPos.Owner:=owner;
780 end;
781 procedure SetLineGeomProps(Pline:PGDBObjLine;args:array of const);
782 var
783 counter:integer;
784 begin
785 counter:=low(args);
786 Pline.CoordInOCS.lBegin:=CreateVertexFromArray(counter,args);
787 Pline.CoordInOCS.lEnd:=CreateVertexFromArray(counter,args);
788 end;
AllocAndCreateLinenull789 function AllocAndCreateLine(owner:PGDBObjGenericWithSubordinated;args:array of const):PGDBObjLine;
790 begin
791 result:=AllocAndInitLine(owner);
792 //owner^.AddMi(@result);
793 SetLineGeomProps(result,args);
794 end;
GDBObjLine.CreateInstancenull795 class function GDBObjLine.CreateInstance:PGDBObjLine;
796 begin
797 result:=AllocAndInitLine(nil);
798 end;
799 begin
800 RegisterDXFEntity(GDBlineID,'LINE','Line',@AllocLine,@AllocAndInitLine,@SetLineGeomProps,@AllocAndCreateLine);
801 end.
802