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