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 uzglvectorobject;
20 {$INCLUDE def.inc}
21 interface
22 uses uzgldrawerabstract,uzgldrawcontext,uzgprimitives,uzglgeomdata,uzgprimitivessarray,
23      gzctnrvectortypes,uzbgeomtypes,uzegeometry,sysutils,uzbtypes,uzbmemman,uzbstrproc,uzbtypesbase;
24 type
25 {Export+}
26 TAppearance=(TAMatching,TANeedProxy);
27 TLLDrawResult=packed record
28                        LLPStart,LLPEndi:TArrayIndex;
29                        LLPCount:TArrayIndex;
30                        Appearance:TAppearance;
31                        BB:TBoundingBox;
32               end;
33 
34 TZGLVectorDataCopyParam=packed record
35                              LLPrimitivesStartIndex:TArrayIndex;
36                              LLPrimitivesDataSize:GDBInteger;
37                              EID:TEntIndexesData;
38                              //GeomIndexMin,GeomIndexMax:TArrayIndex;
39                              GeomDataSize:GDBInteger;
40                              //IndexsDataIndexMax,IndexsDataIndexMin:TArrayIndex;
41                        end;
42 
43 PZGLVectorObject=^ZGLVectorObject;
44 ZGLVectorObject={$IFNDEF DELPHI}packed{$ENDIF} object(GDBaseObject)
45                                  LLprimitives:TLLPrimitivesArray;
46                                  GeomData:ZGLGeomData;
47                                  constructor init({$IFDEF DEBUGBUILD}ErrGuid:pansichar{$ENDIF});
48                                  destructor done;virtual;
49                                  procedure Clear;virtual;
50                                  procedure Shrink;virtual;
CalcTrueInFrustumnull51                                  function CalcTrueInFrustum(frustum:ClipArray; FullCheck:boolean):TInBoundingVolume;virtual;
CalcCountedTrueInFrustumnull52                                  function CalcCountedTrueInFrustum(frustum:ClipArray; FullCheck:boolean;StartOffset,Count:GDBInteger):TInBoundingVolume;virtual;
GetCopyParamnull53                                  function GetCopyParam(LLPStartIndex,LLPCount:GDBInteger):TZGLVectorDataCopyParam;virtual;
CopyTonull54                                  function CopyTo(var dest:ZGLVectorObject;CopyParam:TZGLVectorDataCopyParam):TZGLVectorDataCopyParam;virtual;
55                                  procedure CorrectIndexes(LLPrimitivesStartIndex:GDBInteger;LLPCount:GDBInteger;IndexesStartIndex:GDBInteger;IndexesCount:GDBInteger;offset:TEntIndexesOffsetData);virtual;
56                                  procedure MulOnMatrix(GeomDataIndexMin,GeomDataIndexMax:GDBInteger;const matrix:DMatrix4D);virtual;
GetBoundingBboxnull57                                  function GetBoundingBbox(GeomDataIndexMin,GeomDataIndexMax:GDBInteger):TBoundingBox;virtual;
GetTransformedBoundingBboxnull58                                  function GetTransformedBoundingBbox(GeomDataIndexMin,GeomDataIndexMax:GDBInteger;const matrix:DMatrix4D):TBoundingBox;virtual;
59                                  procedure DrawLLPrimitives(var rc:TDrawContext;var drawer:TZGLAbstractDrawer);virtual;
60                                  procedure DrawCountedLLPrimitives(var rc:TDrawContext;var drawer:TZGLAbstractDrawer;var OptData:ZGLOptimizerData;StartOffset,Count:GDBInteger);virtual;
61                                end;
62 {Export-}
63 implementation
64 procedure ZGLVectorObject.DrawLLPrimitives(var rc:TDrawContext;var drawer:TZGLAbstractDrawer);
65 var
66    PPrimitive:PTLLPrimitive;
67    ProcessedSize:TArrayIndex;
68    CurrentSize:TArrayIndex;
69    OptData:ZGLOptimizerData;
70 begin
71      if LLprimitives.count=0 then exit;
72      OptData.ignoretriangles:=false;
73      OptData.ignorelines:=false;
74      OptData.symplify:=false;
75      ProcessedSize:=0;
76      PPrimitive:=LLprimitives.GetParrayAsPointer;
77      while ProcessedSize<LLprimitives.count do
78      begin
79           CurrentSize:=PPrimitive.draw(Drawer,rc,GeomData,LLprimitives,OptData);
80           ProcessedSize:=ProcessedSize+CurrentSize;
81           inc(pbyte(PPrimitive),CurrentSize);
82      end;
83 end;
84 procedure ZGLVectorObject.DrawCountedLLPrimitives(var rc:TDrawContext;var drawer:TZGLAbstractDrawer;var OptData:ZGLOptimizerData;StartOffset,Count:GDBInteger);
85 var
86    PPrimitive:PTLLPrimitive;
87    ProcessedSize:TArrayIndex;
88    CurrentSize:TArrayIndex;
89 begin
90      if LLprimitives.count<StartOffset+Count then exit;
91      ProcessedSize:=0;
92      PPrimitive:=pointer(LLprimitives.getDataMutable(StartOffset));
93      while count>0 do
94      begin
95           CurrentSize:=PPrimitive.draw(Drawer,rc,GeomData,LLprimitives,OptData);
96           ProcessedSize:=ProcessedSize+CurrentSize;
97           inc(pbyte(PPrimitive),CurrentSize);
98           dec(count);
99      end;
100 end;
101 
102 procedure ZGLVectorObject.CorrectIndexes(LLPrimitivesStartIndex:GDBInteger;LLPCount:GDBInteger;IndexesStartIndex:GDBInteger;IndexesCount:GDBInteger;offset:TEntIndexesOffsetData);
103 var
104    i:integer;
105    CurrLLPrimitiveSize:GDBInteger;
106    PIndex:PGDBInteger;
107    PLLPrimitive:PTLLPrimitive;
108 begin
109      PLLPrimitive:=pointer(LLprimitives.getDataMutable(LLPrimitivesStartIndex));
110      for i:=1 to LLPCount do
111      begin
112           CurrLLPrimitiveSize:=PLLPrimitive.getPrimitiveSize;
113           PLLPrimitive.CorrectIndexes(Offset);
114           inc(pbyte(PLLPrimitive),CurrLLPrimitiveSize);
115      end;
116      if IndexesStartIndex<>-1 then
117      begin
118        PIndex:=GeomData.Indexes.getDataMutable(IndexesStartIndex);
119        for i:=1 to IndexesCount do
120        begin
121             PIndex^:=PIndex^+offset.GeomIndexOffset;
122             inc(PIndex);
123        end;
124      end;
125 end;
126 
ZGLVectorObject.GetCopyParamnull127 function ZGLVectorObject.GetCopyParam(LLPStartIndex,LLPCount:GDBInteger):TZGLVectorDataCopyParam;
128 var
129    i:integer;
130    PLLPrimitive:PTLLPrimitive;
131    CurrLLPrimitiveSize:GDBInteger;
132    eid:TEntIndexesData;
133 procedure ProcessIndexs;
134 begin
135      if eid.GeomIndexMin>=0 then
136        begin
137          if result.EID.GeomIndexMin<0 then
138                                           result.EID.GeomIndexMin:=eid.GeomIndexMin
139                                       else
140                                           begin
141                                                if result.EID.GeomIndexMin>eid.GeomIndexMin then
142                                                                                    result.EID.GeomIndexMin:=eid.GeomIndexMin
143                                           end;
144        end;
145      if eid.GeomIndexMax>=0 then
146        begin
147          if result.EID.GeomIndexMax<0 then
148                                           result.EID.GeomIndexMax:=eid.GeomIndexMax
149                                       else
150                                           begin
151                                                if result.EID.GeomIndexMax<eid.GeomIndexMax then
152                                                                                    result.EID.GeomIndexMax:=eid.GeomIndexMax
153                                           end;
154        end;
155      if eid.IndexsIndexMin>=0 then
156        begin
157          if result.EID.IndexsIndexMin<0 then
158                                           result.EID.IndexsIndexMin:=eid.IndexsIndexMin
159                                       else
160                                           begin
161                                                if result.EID.IndexsIndexMin>eid.IndexsIndexMin then
162                                                                                    result.EID.IndexsIndexMin:=eid.IndexsIndexMin
163                                           end;
164        end;
165      if eid.IndexsIndexMax>=0 then
166        begin
167          if result.EID.IndexsIndexMax<0 then
168                                           result.EID.IndexsIndexMax:=eid.IndexsIndexMax
169                                       else
170                                           begin
171                                                if result.EID.IndexsIndexMax<eid.IndexsIndexMax then
172                                                                                    result.EID.IndexsIndexMax:=eid.IndexsIndexMax
173                                           end;
174        end;
175 end;
176 begin
177      result.LLPrimitivesStartIndex:=LLPStartIndex;
178      PLLPrimitive:=pointer(LLprimitives.getDataMutable(LLPStartIndex));
179      result.LLPrimitivesDataSize:=0;
180      result.EID.GeomIndexMin:=-1;
181      result.EID.GeomIndexMax:=-1;
182      result.EID.IndexsIndexMin:=-1;
183      result.EID.IndexsIndexMax:=-1;
184      for i:=1 to LLPCount do
185      begin
186           CurrLLPrimitiveSize:=PLLPrimitive.getPrimitiveSize;
187           PLLPrimitive.getEntIndexs(GeomData,eid);
188           ProcessIndexs;
189           result.LLPrimitivesDataSize:=result.LLPrimitivesDataSize+CurrLLPrimitiveSize;
190           inc(pbyte(PLLPrimitive),CurrLLPrimitiveSize);
191      end;
192      result.GeomDataSize:=(result.EID.GeomIndexMax-result.EID.GeomIndexMin+1)*GeomData.Vertex3S.SizeOfData;
193 end;
ZGLVectorObject.CopyTonull194 function ZGLVectorObject.CopyTo(var dest:ZGLVectorObject;CopyParam:TZGLVectorDataCopyParam):TZGLVectorDataCopyParam;
195 var
196    LLPrimitivesDestAddr,LLPrimitivesSourceAddr:PTLLPrimitive;
197    DestGeomDataAddr,SourceGeomDataAddr,DestIndexsDataAddr,SourceIndexsDataAddr:PGDBvertex3S;
198 begin
199      result.LLPrimitivesDataSize:=CopyParam.LLPrimitivesDataSize;
200      result.LLPrimitivesStartIndex:=dest.LLprimitives.Count;
201      pointer(LLPrimitivesDestAddr):=dest.LLprimitives.getDataMutable(dest.LLprimitives.AllocData(CopyParam.LLPrimitivesDataSize));
202      LLPrimitivesSourceAddr:=pointer(LLprimitives.getDataMutable(CopyParam.LLPrimitivesStartIndex));
203      Move(LLPrimitivesSourceAddr^,LLPrimitivesDestAddr^,CopyParam.LLPrimitivesDataSize);
204 
205      result.EID.GeomIndexMin:=dest.GeomData.Vertex3S.Count;
206      result.EID.GeomIndexMax:=result.EID.GeomIndexMin+CopyParam.EID.GeomIndexMax-CopyParam.EID.GeomIndexMin;
207      result.GeomDataSize:=CopyParam.GeomDataSize;
208      DestGeomDataAddr:=dest.GeomData.Vertex3S.getDataMutable(dest.GeomData.Vertex3S.AllocData(CopyParam.EID.GeomIndexMax-CopyParam.EID.GeomIndexMin+1));
209      SourceGeomDataAddr:=self.GeomData.Vertex3S.getDataMutable(CopyParam.EID.GeomIndexMin);
210      if (SourceGeomDataAddr<>nil)and(DestGeomDataAddr<>nil) then
211         Move(SourceGeomDataAddr^,DestGeomDataAddr^,CopyParam.GeomDataSize);
212 
213      if CopyParam.EID.IndexsIndexMin<>-1 then
214        begin
215          result.EID.IndexsIndexMin:=dest.GeomData.Indexes.Count;
216          result.EID.IndexsIndexMax:=result.EID.IndexsIndexMin+CopyParam.EID.IndexsIndexMax-CopyParam.EID.IndexsIndexMin;
217          //result.GeomDataSize:=CopyParam.GeomDataSize;
218          pointer(DestIndexsDataAddr):=dest.GeomData.Indexes.getDataMutable(dest.GeomData.Indexes.AllocData(CopyParam.EID.IndexsIndexMax-CopyParam.EID.IndexsIndexMin+1));
219          SourceIndexsDataAddr:=pointer(self.GeomData.Indexes.getDataMutable(CopyParam.EID.IndexsIndexMin));
220          Move(SourceIndexsDataAddr^,DestIndexsDataAddr^,(CopyParam.EID.IndexsIndexMax-CopyParam.EID.IndexsIndexMin+1)*GeomData.Indexes.SizeOfData);
221        end
222      else
223        begin
224           result.EID.IndexsIndexMin:=-1;
225           result.EID.IndexsIndexMax:=-1;
226        end;
227 end;
228 procedure ZGLVectorObject.MulOnMatrix(GeomDataIndexMin,GeomDataIndexMax:GDBInteger;const matrix:DMatrix4D);
229 var
230    i:integer;
231    p:PGDBvertex3S;
232 begin
233      p:=self.GeomData.Vertex3S.getDataMutable(GeomDataIndexMin);
234      for i:=0 to GeomDataIndexMax-GeomDataIndexMin do
235      begin
236        p^:=VectorTransform3D(p^,matrix);
237        inc(p);
238      end;
239 end;
ZGLVectorObject.GetBoundingBboxnull240 function ZGLVectorObject.GetBoundingBbox(GeomDataIndexMin,GeomDataIndexMax:GDBInteger):TBoundingBox;
241 var
242    i:integer;
243    p:PGDBvertex3S;
244 begin
245      result.LBN:=InfinityVertex;
246      result.RTF:=MinusInfinityVertex;
247      p:=self.GeomData.Vertex3S.getDataMutable(GeomDataIndexMin);
248      for i:=0 to GeomDataIndexMax-GeomDataIndexMin do
249      begin
250        if result.LBN.x>p.x then
251                                result.LBN.x:=p.x;
252        if result.LBN.y>p.y then
253                                result.LBN.y:=p.y;
254        if result.LBN.z>p.z then
255                                result.LBN.z:=p.z;
256        if result.RTF.x<p.x then
257                                result.RTF.x:=p.x;
258        if result.RTF.y<p.y then
259                                result.RTF.y:=p.y;
260        if result.RTF.z<p.z then
261                                result.RTF.z:=p.z;
262        inc(p);
263      end;
264 end;
ZGLVectorObject.GetTransformedBoundingBboxnull265 function ZGLVectorObject.GetTransformedBoundingBbox(GeomDataIndexMin,GeomDataIndexMax:GDBInteger;const matrix:DMatrix4D):TBoundingBox;
266 var
267    i:integer;
268    p:PGDBvertex3S;
269    point:GDBvertex3S;
270 begin
271      result.LBN:=InfinityVertex;
272      result.RTF:=MinusInfinityVertex;
273      p:=self.GeomData.Vertex3S.getDataMutable(GeomDataIndexMin);
274      for i:=0 to GeomDataIndexMax-GeomDataIndexMin do
275      begin
276        point:=VectorTransform3D(p^,matrix);
277        if result.LBN.x>point.x then
278                                result.LBN.x:=point.x;
279        if result.LBN.y>point.y then
280                                result.LBN.y:=point.y;
281        if result.LBN.z>point.z then
282                                result.LBN.z:=point.z;
283        if result.RTF.x<point.x then
284                                result.RTF.x:=point.x;
285        if result.RTF.y<point.y then
286                                result.RTF.y:=point.y;
287        if result.RTF.z<point.z then
288                                result.RTF.z:=point.z;
289        inc(p);
290      end;
291 end;
ZGLVectorObject.CalcCountedTrueInFrustumnull292 function ZGLVectorObject.CalcCountedTrueInFrustum(frustum:ClipArray; FullCheck:boolean;StartOffset,Count:GDBInteger):TInBoundingVolume;
293 var
294   //subresult:TInBoundingVolume;
295   PPrimitive:PTLLPrimitive;
296   ProcessedSize:TArrayIndex;
297   CurrentSize:TArrayIndex;
298   InRect:TInBoundingVolume;
299 begin
300   if StartOffset>=LLprimitives.count then
301                                         begin
302                                           result:=IREmpty;
303                                           exit;
304                                         end;
305   ProcessedSize:=0;
306   PPrimitive:=pointer(LLprimitives.getDataMutable(StartOffset));
307   if count>0 then
308   begin
309        CurrentSize:=PPrimitive.CalcTrueInFrustum(frustum,GeomData,result);
310        if not FullCheck then
311          if result<>IREmpty then
312            exit;
313        if result=IRPartially then
314                                  exit;
315        ProcessedSize:=ProcessedSize+CurrentSize;
316        inc(pbyte(PPrimitive),CurrentSize);
317        dec(count);
318   end;
319   while count>0 do
320   begin
321        CurrentSize:=PPrimitive.CalcTrueInFrustum(frustum,GeomData,InRect);
322        case InRect of
323          IREmpty:if result=IRFully then
324                                         result:=IRPartially;
325          IRFully:if result<>IRFully then
326                                         result:=IRPartially;
327          IRPartially:
328                      result:=IRPartially;
329        end;
330        if result=IRPartially then
331                                  exit;
332        if not FullCheck then
333          if result<>IREmpty then
334            exit;
335        ProcessedSize:=ProcessedSize+CurrentSize;
336        inc(pbyte(PPrimitive),CurrentSize);
337        dec(count);
338   end;
339 end;
340 
ZGLVectorObject.CalcTrueInFrustumnull341 function ZGLVectorObject.CalcTrueInFrustum(frustum:ClipArray; FullCheck:boolean):TInBoundingVolume;
342 var
343   //subresult:TInBoundingVolume;
344   PPrimitive:PTLLPrimitive;
345   ProcessedSize:TArrayIndex;
346   CurrentSize:TArrayIndex;
347   InRect:TInBoundingVolume;
348 begin
349   if LLprimitives.count=0 then
350                               begin
351                                 result:=IREmpty;
352                                 exit;
353                               end;
354   ProcessedSize:=0;
355   PPrimitive:=LLprimitives.GetParrayAsPointer;
356   if ProcessedSize<LLprimitives.count then
357   begin
358        CurrentSize:=PPrimitive.CalcTrueInFrustum(frustum,GeomData,result);
359        if not FullCheck then
360          if result<>IREmpty then
361                                 begin
362                                      result:=IRPartially;
363                                      exit;
364                                 end;
365        if result=IRPartially then
366                                  exit;
367        ProcessedSize:=ProcessedSize+CurrentSize;
368        inc(pbyte(PPrimitive),CurrentSize);
369   end;
370   while ProcessedSize<LLprimitives.count do
371   begin
372        CurrentSize:=PPrimitive.CalcTrueInFrustum(frustum,GeomData,InRect);
373        case InRect of
374          IREmpty:if result=IRFully then
375                                         result:=IRPartially;
376          IRFully:if result<>IRFully then
377                                         result:=IRPartially;
378          IRPartially:
379                      result:=IRPartially;
380        end;
381        if result=IRPartially then
382                                  exit;
383        if not FullCheck then
384          if result<>IREmpty then
385            exit;
386        ProcessedSize:=ProcessedSize+CurrentSize;
387        inc(pbyte(PPrimitive),CurrentSize);
388   end;
389 end;
390 
391 constructor ZGLVectorObject.init;
392 begin
393   GeomData.init({$IFDEF DEBUGBUILD}pchar({$IFDEF SEPARATEMEMUSAGE}ErrGuid+{$ENDIF}'{ZGLVectorObject.GeomData}'),{$ENDIF}100);
394   LLprimitives.init({$IFDEF DEBUGBUILD}pchar({$IFDEF SEPARATEMEMUSAGE}ErrGuid+{$ENDIF}'{ZGLVectorObject.LLprimitives}'),{$ENDIF}100);
395 end;
396 destructor ZGLVectorObject.done;
397 begin
398   GeomData.done;
399   LLprimitives.done;
400 end;
401 procedure ZGLVectorObject.Clear;
402 begin
403   GeomData.Clear;
404   LLprimitives.Clear;
405 end;
406 procedure ZGLVectorObject.Shrink;
407 begin
408   GeomData.Shrink;
409   LLprimitives.Shrink;
410 end;
411 begin
412 end.
413 
414