b311480e |
1 | // Created on: 2002-02-04 |
2 | // Created by: Peter KURNEV |
3 | // Copyright (c) 2002-2012 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
7fd59977 |
20 | |
21 | #include <BOP_WireShape.ixx> |
22 | |
23 | #include <TopoDS.hxx> |
24 | #include <TopoDS_Compound.hxx> |
25 | #include <TopoDS_Edge.hxx> |
26 | #include <TopoDS_Shape.hxx> |
27 | #include <TopoDS_Vertex.hxx> |
28 | #include <TopoDS_Wire.hxx> |
29 | |
30 | #include <TopAbs_ShapeEnum.hxx> |
31 | #include <TopAbs_Orientation.hxx> |
32 | |
33 | #include <TopTools_ListOfShape.hxx> |
34 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
35 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
36 | #include <TopTools_IndexedMapOfShape.hxx> |
37 | |
38 | #include <TopExp.hxx> |
39 | #include <TopExp_Explorer.hxx> |
40 | |
41 | #include <BRep_Tool.hxx> |
42 | #include <BRep_Builder.hxx> |
43 | |
44 | #include <BOPTools_DSFiller.hxx> |
45 | #include <BOPTools_PaveFiller.hxx> |
46 | #include <BOPTools_SplitShapesPool.hxx> |
47 | #include <BOPTools_PaveBlock.hxx> |
48 | #include <BOPTools_ListOfPaveBlock.hxx> |
49 | #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx> |
50 | #include <BOPTools_CommonBlockPool.hxx> |
51 | #include <BOPTools_CommonBlock.hxx> |
52 | #include <BOPTools_ListOfCommonBlock.hxx> |
53 | #include <BOPTools_ListIteratorOfListOfCommonBlock.hxx> |
54 | |
55 | #include <BOP_CorrectTolerances.hxx> |
56 | #include <BOP_BuilderTools.hxx> |
57 | |
58 | #include <BooleanOperations_ShapesDataStructure.hxx> |
59 | #include <BooleanOperations_StateOfShape.hxx> |
60 | |
61 | #include <BOP_BuilderTools.hxx> |
62 | #include <BOP_ConnexityBlock.hxx> |
63 | #include <BOP_ListOfConnexityBlock.hxx> |
64 | #include <BOP_ListIteratorOfListOfConnexityBlock.hxx> |
65 | |
66 | |
67 | static |
68 | Standard_Integer InOrOut(const TopoDS_Vertex& , |
69 | const TopoDS_Edge& ); |
70 | static |
71 | TopAbs_Orientation Orientation(const TopoDS_Vertex& , |
72 | const TopoDS_Edge& ); |
73 | static |
74 | void OrientEdgesOnWire(const TopoDS_Wire& , |
75 | TopoDS_Wire& ); |
76 | |
77 | //======================================================================= |
78 | // function: BOP_WireShape::BOP_WireShape |
79 | // purpose: |
80 | //======================================================================= |
81 | BOP_WireShape::BOP_WireShape() |
82 | { |
83 | } |
84 | //======================================================================= |
85 | // function: MakeResult |
86 | // purpose: |
87 | //======================================================================= |
88 | void BOP_WireShape::MakeResult() |
89 | { |
90 | BRep_Builder aBB; |
91 | TopoDS_Compound aCompound; |
92 | |
93 | aBB.MakeCompound(aCompound); |
94 | |
95 | TopoDS_Wire aWNew; |
96 | BOP_ListOfConnexityBlock aLCB; |
97 | BOP_BuilderTools::MakeConnexityBlocks(myLS, TopAbs_EDGE, aLCB); |
98 | BOP_ListIteratorOfListOfConnexityBlock aLCBIt(aLCB); |
99 | for (; aLCBIt.More(); aLCBIt.Next()) { |
100 | const BOP_ConnexityBlock& aCB=aLCBIt.Value(); |
101 | const TopTools_ListOfShape& aLE=aCB.Shapes(); |
102 | TopoDS_Wire aW; |
103 | aBB.MakeWire(aW); |
104 | TopTools_ListIteratorOfListOfShape anIt(aLE); |
105 | for (; anIt.More(); anIt.Next()) { |
106 | const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value()); |
107 | aBB.Add(aW, aE); |
108 | } |
109 | OrientEdgesOnWire(aW, aWNew); |
110 | aBB.Add(aCompound, aWNew); |
111 | } |
112 | myResult=aCompound; |
113 | } |
114 | |
115 | //======================================================================= |
116 | // function: AddSplitPartsINOUT |
117 | // purpose: |
118 | //======================================================================= |
119 | void BOP_WireShape::AddSplitPartsINOUT() |
120 | { |
121 | const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS(); |
122 | const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller(); |
123 | const BOPTools_SplitShapesPool& aSplitShapesPool=aPaveFiller.SplitShapesPool(); |
124 | // |
125 | Standard_Integer i, aNbPB, iRank, nSp, iBeg, iEnd; |
126 | TopAbs_ShapeEnum aType, aTypeArg1, aTypeArg2; |
127 | BooleanOperations_StateOfShape aState, aStateCmp; |
128 | // |
129 | aTypeArg1=aDS.Object().ShapeType(); |
130 | aTypeArg2=aDS.Tool().ShapeType(); |
131 | |
132 | iBeg=1; |
133 | iEnd=aDS.NumberOfShapesOfTheObject(); |
134 | |
135 | if (aTypeArg1!=TopAbs_WIRE && aTypeArg2==TopAbs_WIRE) { |
136 | iBeg=iEnd+1; |
137 | iEnd=aDS.NumberOfSourceShapes(); |
138 | } |
139 | else if (aTypeArg1==TopAbs_WIRE && aTypeArg2==TopAbs_WIRE){ |
140 | iBeg=1; |
141 | iEnd=aDS.NumberOfSourceShapes(); |
142 | } |
143 | // |
144 | |
145 | for (i=iBeg; i<=iEnd; ++i) { |
146 | aType=aDS.GetShapeType(i); |
147 | if (aType!=TopAbs_EDGE) { |
148 | continue; |
149 | } |
150 | const TopoDS_Edge& aE=TopoDS::Edge(aDS.Shape(i)); |
151 | |
152 | iRank=aDS.Rank(i); |
153 | aStateCmp=BOP_BuilderTools::StateToCompare(iRank, myOperation); |
154 | |
155 | const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(aDS.RefEdge(i)); |
156 | aNbPB=aLPB.Extent(); |
157 | // |
158 | if (!aNbPB) { |
159 | aState=aDS.GetState(i); |
160 | if (aState==aStateCmp) { |
161 | myLS.Append(aE); |
162 | } |
163 | } |
164 | // |
165 | else { |
166 | BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aLPB); |
167 | for (; aPBIt.More(); aPBIt.Next()) { |
168 | const BOPTools_PaveBlock& aPB=aPBIt.Value(); |
169 | nSp=aPB.Edge(); |
170 | const TopoDS_Edge& aSS=TopoDS::Edge(aDS.Shape(nSp)); |
171 | aState=aDS.GetState(nSp); |
172 | if (aState==aStateCmp) { |
173 | myLS.Append(aSS); |
174 | } |
175 | } |
176 | } |
177 | } |
178 | } |
179 | |
180 | //======================================================================= |
181 | // function: AddSplitPartsON |
182 | // purpose: |
183 | //======================================================================= |
184 | void BOP_WireShape::AddSplitPartsON() |
185 | { |
186 | if (myOperation==BOP_CUT || myOperation==BOP_CUT21) { |
187 | return; |
188 | } |
189 | |
190 | const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS(); |
191 | const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller(); |
192 | const BOPTools_CommonBlockPool& aCommonBlockPool=aPaveFiller.CommonBlockPool(); |
193 | |
194 | Standard_Integer i, aNbCB, nSpTaken, iBeg, iEnd; |
195 | TopAbs_ShapeEnum aType, aTypeArg1, aTypeArg2; |
196 | BOPTools_ListIteratorOfListOfCommonBlock anItCB; |
197 | // |
198 | aTypeArg1=aDS.Object().ShapeType(); |
199 | aTypeArg2=aDS.Tool().ShapeType(); |
200 | |
201 | iBeg=1; |
202 | iEnd=aDS.NumberOfShapesOfTheObject(); |
203 | if (aTypeArg1!=TopAbs_WIRE && aTypeArg2==TopAbs_WIRE) { |
204 | iBeg=iEnd+1; |
205 | iEnd=aDS.NumberOfSourceShapes(); |
206 | } |
207 | else if (aTypeArg1==TopAbs_WIRE && aTypeArg2==TopAbs_WIRE){ |
208 | iEnd=aDS.NumberOfSourceShapes(); |
209 | } |
210 | // |
211 | for (i=iBeg; i<=iEnd; ++i) { |
212 | aType=aDS.GetShapeType(i); |
213 | if (aType!=TopAbs_EDGE) { |
214 | continue; |
215 | } |
216 | // |
217 | const BOPTools_ListOfCommonBlock& aLCB=aCommonBlockPool(aDS.RefEdge(i)); |
218 | aNbCB=aLCB.Extent(); |
219 | |
220 | anItCB.Initialize(aLCB); |
221 | for (; anItCB.More(); anItCB.Next()) { |
222 | BOPTools_CommonBlock& aCB=anItCB.Value(); |
223 | const BOPTools_PaveBlock& aPB=aCB.PaveBlock1(); |
224 | nSpTaken=aPB.Edge(); |
225 | const TopoDS_Edge& aSS=TopoDS::Edge(aDS.Shape(nSpTaken)); |
226 | myLS.Append(aSS); |
227 | } |
228 | } |
229 | } |
230 | |
231 | //======================================================================= |
232 | // function: OrientEdgesOnWire |
233 | // purpose: |
234 | //======================================================================= |
235 | void OrientEdgesOnWire(const TopoDS_Wire& aWire, |
236 | TopoDS_Wire& aWireNew) |
237 | { |
238 | Standard_Integer i, aNbV, aNbE, j, iCnt, iInOrOut, aNbRest; |
239 | |
240 | TopTools_IndexedDataMapOfShapeListOfShape aVEMap; |
241 | TopTools_IndexedMapOfShape aProcessedEdges, aRestEdges, aEMap; |
242 | TopTools_ListIteratorOfListOfShape anIt; |
243 | BRep_Builder aBB; |
244 | |
245 | aBB.MakeWire(aWireNew); |
246 | |
247 | TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, aVEMap); |
248 | |
249 | aNbV=aVEMap.Extent(); |
250 | // |
251 | // Do |
252 | for (i=1; i<=aNbV; i++) { |
253 | const TopoDS_Vertex& aV=TopoDS::Vertex(aVEMap.FindKey(i)); |
254 | |
255 | const TopTools_ListOfShape& aLE=aVEMap.FindFromIndex(i); |
256 | aNbE=aLE.Extent(); |
257 | |
258 | if (aNbE>=2) { |
259 | iCnt=0; |
260 | anIt.Initialize(aLE); |
261 | for(; anIt.More(); anIt.Next()) { |
262 | const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value()); |
263 | if (aProcessedEdges.Contains(aE)) { |
264 | iInOrOut=InOrOut(aV, aE); |
265 | iCnt+=iInOrOut; |
266 | } |
267 | else { |
268 | aRestEdges.Add(aE); |
269 | } |
270 | } |
271 | |
272 | TopoDS_Edge* pE; |
273 | aNbRest=aRestEdges.Extent(); |
274 | for (j=1; j<=aNbRest; j++) { |
275 | const TopoDS_Edge& aE=TopoDS::Edge(aRestEdges(j)); |
276 | pE=(TopoDS_Edge*)&aE; |
277 | |
278 | iInOrOut=InOrOut(aV, aE); |
279 | if (iCnt>0) { |
280 | if (iInOrOut>0) { |
281 | pE->Reverse(); |
282 | } |
283 | --iCnt; |
284 | } |
285 | else if (iCnt<=0){ |
286 | if (iInOrOut<0) { |
287 | pE->Reverse(); |
288 | } |
289 | ++iCnt; |
290 | } |
291 | aProcessedEdges.Add(*pE); |
292 | } |
293 | }//if (aNbE>=2) |
294 | } |
295 | // |
296 | // |
297 | aNbE=aProcessedEdges.Extent(); |
298 | for (i=1; i<=aNbE; i++) { |
299 | const TopoDS_Edge& aE=TopoDS::Edge(aProcessedEdges(i)); |
300 | aBB.Add(aWireNew, aE); |
301 | } |
302 | |
303 | TopExp::MapShapes(aWire, TopAbs_EDGE, aEMap); |
304 | |
305 | aNbE=aEMap.Extent(); |
306 | for (i=1; i<=aNbE; i++) { |
307 | const TopoDS_Edge& aE=TopoDS::Edge(aEMap(i)); |
308 | if (!aProcessedEdges.Contains(aE)) { |
309 | aProcessedEdges.Add(aE); |
310 | aBB.Add(aWireNew, aE); |
311 | } |
312 | } |
313 | } |
314 | |
315 | //======================================================================= |
316 | //function : Orientation |
317 | //purpose : |
318 | //======================================================================= |
319 | TopAbs_Orientation Orientation(const TopoDS_Vertex& aV, |
320 | const TopoDS_Edge& aE) |
321 | { |
322 | TopAbs_Orientation anOr=TopAbs_INTERNAL; |
323 | |
324 | TopExp_Explorer anExp; |
325 | anExp.Init(aE, TopAbs_VERTEX); |
326 | for (; anExp.More(); anExp.Next()) { |
327 | const TopoDS_Vertex& aVE1=TopoDS::Vertex(anExp.Current()); |
328 | if (aVE1.IsSame(aV)) { |
329 | anOr=aVE1.Orientation(); |
330 | break; |
331 | } |
332 | } |
333 | return anOr; |
334 | } |
335 | |
336 | ///======================================================================= |
337 | //function : InOrOut |
338 | //purpose : |
339 | //======================================================================= |
340 | Standard_Integer InOrOut(const TopoDS_Vertex& aV, |
341 | const TopoDS_Edge& aE) |
342 | { |
343 | TopAbs_Orientation anOrV, anOrE; |
344 | anOrV=aV.Orientation(); |
345 | anOrE=aE.Orientation(); |
346 | if (anOrV==TopAbs_INTERNAL){ |
347 | return 0; |
348 | } |
349 | |
350 | anOrV=Orientation(aV, aE); |
351 | |
352 | if (anOrV==anOrE) { |
353 | return -1; // escape |
354 | } |
355 | else { |
356 | return 1; // entry |
357 | } |
358 | } |