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 uzegeomentitiestree;
20 {$INCLUDE def.inc}
21 interface
22 uses
23     graphics,{gzctnrvectorsimple,}uzgeomentity,{gzctnrvectordata,}uzctnrobjectschunk,
24     gzctnrvectortypes,uzbgeomtypes,gzctnrtree,{uzgldrawcontext,}uzegeometry,uzbtypesbase,uzbtypes,uzbmemman;
25 type
26 TZEntsManipulator=class;
27 TFirstStageData=record
28                   midlepoint:gdbvertex;
29                   d:double;
30                   counter:integer;
31                 end;
32 {EXPORT+}
33 TGeomTreeNodeData=packed record
34                   end;
35 TEntityArray={$IFNDEF DELPHI}packed{$ENDIF} object(TObjectsChunk)(*OpenArrayOfData=GDBByte*)
36 end;
37          PTEntTreeNode=^TGeomEntTreeNode;
38          TGeomEntTreeNode={$IFNDEF DELPHI}packed{$ENDIF}object(GZBInarySeparatedGeometry{-}<TBoundingBox,DVector4D,TGeomTreeNodeData,TZEntsManipulator,TGeomEntity,PTGeomEntity,TEntityArray>{//})
39             {-}{/pplusnode,pminusnode:PTEntTreeNode;/}
40             {-}{/nul:TEntityArray;/}
41             {-}{/Separator:DVector4D;/}
42             {-}{/BoundingBox:TBoundingBox;/}
43             {-}{/NodeDir:TNodeDir;/}
44             {-}{/Root:GDBPointer;/}
45             {-}{/NodeData:TGeomTreeNodeData;/}
46             {-}{/LockCounter:GDBInteger;/}
47                       end;
48 {EXPORT-}
49 TZEntsManipulator=class
50                    class procedure StoreTreeAdressInOnject(var Entity:TGeomEntity;var Node:GZBInarySeparatedGeometry<TBoundingBox,DVector4D,TGeomTreeNodeData,TZEntsManipulator,TGeomEntity,PTGeomEntity,TEntityArray>;const index:GDBInteger);
51                    class procedure CorrectNodeBoundingBox(var NodeBB:TBoundingBox;var Entity:TGeomEntity);
GetEntityBoundingBoxnull52                    class function GetEntityBoundingBox(var Entity:TGeomEntity):TBoundingBox;
GetBBPositionnull53                    class function GetBBPosition(const sep:DVector4D;const BB:TBoundingBox):TElemPosition;
isUnneedSeparatenull54                    class function isUnneedSeparate(const count,depth:integer):boolean;
GetTestNodesCountnull55                    class function GetTestNodesCount:integer;
56                    class procedure FirstStageCalcSeparatirs(var NodeBB:TBoundingBox;var Entity:TGeomEntity;var PFirstStageData:pointer;TSM:TStageMode);
57                    class procedure CreateSeparator(var NodeBB:TBoundingBox;var TestNode:TGeomEntTreeNode.TTestNode;var PFirstStageData:pointer;const NodeNum:integer);
IterateResult2PEntitynull58                    class function IterateResult2PEntity(const IterateResult:pointer):PTGeomEntity;
StoreEntityToArraynull59                    class function StoreEntityToArray(var Entity:TGeomEntity;var arr:TEntityArray):TArrayIndex;
60                   end;
61 var
62    SysVarRDSpatialNodeCount:integer=2;
63    SysVarRDSpatialNodesDepth:integer=20;
64    FirstStageData:TFirstStageData;
GetInNodeCountnull65 function GetInNodeCount(_InNodeCount:GDBInteger):GDBInteger;
66 implementation
TZEntsManipulator.StoreEntityToArraynull67 class function TZEntsManipulator.StoreEntityToArray(var Entity:TGeomEntity;var arr:TEntityArray):TArrayIndex;
68 begin
69      //arr.pushBackData(Entity);
70      result:=arr.AddData(@Entity,sizeof(entity));
71 end;
TZEntsManipulator.isUnneedSeparatenull72 class function TZEntsManipulator.isUnneedSeparate(const count,depth:integer):boolean;
73 begin
74      if (Count<=GetInNodeCount(SysVarRDSpatialNodeCount))or(depth>=SysVarRDSpatialNodesDepth) then
75        result:=true
76      else
77        result:=false;
78 end;
TZEntsManipulator.GetTestNodesCountnull79 class function TZEntsManipulator.GetTestNodesCount:integer;
80 begin
81    result:=1;
82 end;
83 class procedure TZEntsManipulator.FirstStageCalcSeparatirs(var NodeBB:TBoundingBox;var Entity:TGeomEntity;var PFirstStageData:pointer;TSM:TStageMode);
84 begin
85    case TSM of
86        TSMStart:begin
87                    FirstStageData.midlepoint:=NulVertex;
88                    FirstStageData.counter:=0;
89                    PFirstStageData:={@FirstStageData}nil;
90                 end;
91 TSMAccumulation:begin
92                    //FirstStageData.midlepoint:=vertexadd(Entity.GetBB.LBN,FirstStageData.midlepoint);
93                    //FirstStageData.midlepoint:=vertexadd(Entity.GetBB.RTF,FirstStageData.midlepoint);
94                    //inc(FirstStageData.counter,2);
95                 end;
96         TSMCalc:begin
97                    //FirstStageData.midlepoint:=VertexMulOnSc(FirstStageData.midlepoint,1/FirstStageData.counter);
98                    //FirstStageData.d:=sqrt(sqr(FirstStageData.midlepoint.x) + sqr(FirstStageData.midlepoint.y) + sqr(FirstStageData.midlepoint.z));
99                 end;
100          TSMEnd:begin
101                    PFirstStageData:=nil;
102                 end;
103    end;
104 end;
105 class procedure TZEntsManipulator.CreateSeparator(var NodeBB:TBoundingBox;var TestNode:TGeomEntTreeNode.TTestNode;var PFirstStageData:pointer;const NodeNum:integer);
106 var
107    v:gdbvertex;
108    axis:integer;
109 begin
110    v:=VertexSub(NodeBB.RTF,NodeBB.LBN);
111    if v.x>v.y then
112               begin
113                    if v.x>v.z then
114                               axis:=0
115                           else
116                               axis:=2
117               end
118           else
119               begin
120                    if v.y>v.z then
121                               axis:=1
122                           else
123                               axis:=2
124               end;
125    FirstStageData.midlepoint:=VertexMulOnSc(VertexAdd(NodeBB.RTF,NodeBB.LBN),0.5);
126    FirstStageData.d:=sqrt(sqr(FirstStageData.midlepoint.x) + sqr(FirstStageData.midlepoint.y) + sqr(FirstStageData.midlepoint.z));
127 case axis of
128       0:TestNode.plane:=uzegeometry.PlaneFrom3Pont(FirstStageData.midlepoint,
129                                           vertexadd(FirstStageData.midlepoint,VertexMulOnSc(x_Y_zVertex,FirstStageData.d)),
130                                           vertexadd(FirstStageData.midlepoint,VertexMulOnSc(xy_Z_Vertex,FirstStageData.d))
131                                           );
132       1:TestNode.plane:=uzegeometry.PlaneFrom3Pont(FirstStageData.midlepoint,
133                                           vertexadd(FirstStageData.midlepoint,VertexMulOnSc(_X_yzVertex,FirstStageData.d)),
134                                           vertexadd(FirstStageData.midlepoint,VertexMulOnSc(xy_Z_Vertex,FirstStageData.d))
135                                           );
136       2:TestNode.plane:=uzegeometry.PlaneFrom3Pont(FirstStageData.midlepoint,
137                                           vertexadd(FirstStageData.midlepoint,VertexMulOnSc(_X_yzVertex,FirstStageData.d)),
138                                           vertexadd(FirstStageData.midlepoint,VertexMulOnSc(x_Y_ZVertex,FirstStageData.d))
139                                           );
140 end;
141 end;
142 class procedure TZEntsManipulator.StoreTreeAdressInOnject(var Entity:TGeomEntity;var Node:GZBInarySeparatedGeometry{-}<TBoundingBox,DVector4D,TgeomTreeNodeData,TZEntsManipulator,TGeomEntity,PTGeomEntity,TEntityArray>;const index:GDBInteger);
143 begin
144   {Entity.bp.TreePos.Owner:=@Node;
145   Entity.bp.TreePos.SelfIndex:=index;}
146 end;
147 class procedure TZEntsManipulator.CorrectNodeBoundingBox(var NodeBB:TBoundingBox;var Entity:TGeomEntity);
148 begin
149      ConcatBB(NodeBB,GetEntityBoundingBox(Entity));
150 end;
TZEntsManipulator.GetEntityBoundingBoxnull151 class function TZEntsManipulator.GetEntityBoundingBox(var Entity:TGeomEntity):TBoundingBox;
152 begin
153      result:=Entity.GetBB;
154 end;
155 
TZEntsManipulator.GetBBPositionnull156 class function TZEntsManipulator.GetBBPosition(const sep:DVector4D;const BB:TBoundingBox):TElemPosition;
157 var
158     d,d1,d2:double;
159 begin
160      d1:=sep[0] * BB.RTF.x + sep[1] * BB.RTF.y + sep[2] * BB.RTF.z + sep[3];
161      d2:=sep[0] * BB.LBN.x + sep[1] * BB.LBN.y + sep[2] * BB.LBN.z + sep[3];
162      if abs(d1)<eps then
163                         d1:=0;
164      if abs(d2)<eps then
165                         d2:=0;
166      d:=d1*d2;
167 
168      if d=0 then
169                 begin
170                      if (d1=0)and(d2=0) then
171                                             exit(TEP_nul)
172                                             //ta[i].nul.PushBackData(pobj)
173                 else if (d1>0)or(d2>0)  then
174                                             exit(TEP_Plus)
175                                             //ta[i].plus.PushBackData(pobj)
176                                         else
177                                             exit(TEP_Minus)
178                                             //ta[i].minus.PushBackData(pobj);
179                 end
180 else if d<0 then
181                 exit(TEP_nul)
182                 //ta[i].nul.PushBackData(pobj)
183 else if (d1>0)or(d2>0)  then
184                             exit(TEP_Plus)
185                             //ta[i].plus.PushBackData(pobj)
186                         else
187                             exit(TEP_Minus)
188                             //ta[i].minus.PushBackData(pobj);
189      //result:=TEP_nul;
190 end;
TZEntsManipulator.IterateResult2PEntitynull191 class function TZEntsManipulator.IterateResult2PEntity(const IterateResult:pointer):PTGeomEntity;
192 begin
193   {if IterateResult<>nil then
194     result:=ppointer(IterateResult)^
195   else
196     result:=nil;}
197   result:=IterateResult;
198 end;
199 
GetInNodeCountnull200 function GetInNodeCount(_InNodeCount:GDBInteger):GDBInteger;
201 begin
202      if _InNodeCount>0 then
203                            result:=_InNodeCount
204                        else
205                            result:=500;
206 end;
207 begin
208 end.
209