Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-09-03 |
2 | // Created by: Yves FRICAUD | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
17 | // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 | |
18 | ||
7fd59977 | 19 | #include <BRep_Builder.hxx> |
20 | #include <BRep_Tool.hxx> | |
42cf5bc1 | 21 | #include <BRepAdaptor_Curve.hxx> |
22 | #include <BRepAlgo_AsDes.hxx> | |
23 | #include <BRepAlgo_Image.hxx> | |
7fd59977 | 24 | #include <BRepLib_MakeVertex.hxx> |
42cf5bc1 | 25 | #include <BRepOffset_Analyse.hxx> |
26 | #include <BRepOffset_DataMapOfShapeOffset.hxx> | |
27 | #include <BRepOffset_Inter3d.hxx> | |
28 | #include <BRepOffset_Interval.hxx> | |
29 | #include <BRepOffset_ListOfInterval.hxx> | |
30 | #include <BRepOffset_Offset.hxx> | |
31 | #include <BRepOffset_Tool.hxx> | |
32 | #include <Extrema_ExtPC.hxx> | |
9b7f3f83 | 33 | #include <GeomAPI_ProjectPointOnCurve.hxx> |
42cf5bc1 | 34 | #include <Precision.hxx> |
7fd59977 | 35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> | |
37 | #include <TopoDS.hxx> | |
38 | #include <TopoDS_Compound.hxx> | |
39 | #include <TopoDS_Edge.hxx> | |
42cf5bc1 | 40 | #include <TopoDS_Face.hxx> |
41 | #include <TopoDS_Shape.hxx> | |
7fd59977 | 42 | #include <TopoDS_Vertex.hxx> |
43 | #include <TopOpeBRepTool_BoxSort.hxx> | |
42cf5bc1 | 44 | #include <TopTools_IndexedMapOfShape.hxx> |
7fd59977 | 45 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
46 | #include <TopTools_MapIteratorOfMapOfShape.hxx> | |
975ec82a | 47 | #include <TopTools_MapOfShape.hxx> |
ecf4f17c | 48 | // |
49 | #include <BOPTools_AlgoTools.hxx> | |
7fd59977 | 50 | |
51 | //======================================================================= | |
52 | //function : BRepOffset_Inter3d | |
53 | //purpose : | |
54 | //======================================================================= | |
7fd59977 | 55 | BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes, |
9b7f3f83 | 56 | const TopAbs_State Side , |
57 | const Standard_Real Tol) | |
7fd59977 | 58 | :myAsDes(AsDes), |
59 | mySide(Side), | |
60 | myTol(Tol) | |
61 | { | |
62 | } | |
63 | ||
64 | ||
65 | //======================================================================= | |
66 | //function : ExtentEdge | |
67 | //purpose : | |
68 | //======================================================================= | |
69 | ||
35e08fe8 | 70 | static void ExtentEdge(const TopoDS_Face& /*F*/, |
9b7f3f83 | 71 | const TopoDS_Edge& E, |
72 | TopoDS_Edge& NE) | |
7fd59977 | 73 | { |
74 | TopoDS_Shape aLocalShape = E.EmptyCopied(); | |
75 | NE = TopoDS::Edge(aLocalShape); | |
76 | // NE = TopoDS::Edge(E.EmptyCopied()); | |
77 | ||
78 | ||
0d969553 Y |
79 | // Enough for analytic edges, in general case reconstruct the |
80 | // geometry of the edge recalculating the intersection of surfaces. | |
7fd59977 | 81 | |
82 | NE.Orientation(TopAbs_FORWARD); | |
83 | Standard_Real f,l; | |
84 | BRep_Tool::Range(E,f,l); | |
85 | Standard_Real length = l-f; | |
86 | f -= 100*length; | |
87 | l += 100*length; | |
88 | ||
89 | BRep_Builder B; | |
90 | B.Range(NE,f,l); | |
91 | BRepAdaptor_Curve CE(E); | |
92 | TopoDS_Vertex V1 = BRepLib_MakeVertex(CE.Value(f)); | |
93 | TopoDS_Vertex V2 = BRepLib_MakeVertex(CE.Value(l)); | |
94 | B.Add(NE,V1.Oriented(TopAbs_FORWARD)); | |
95 | B.Add(NE,V2.Oriented(TopAbs_REVERSED)); | |
96 | NE.Orientation(E.Orientation()); | |
97 | ||
98 | } | |
99 | ||
100 | //======================================================================= | |
101 | //function : SelectEdge | |
102 | //purpose : | |
103 | //======================================================================= | |
9b7f3f83 | 104 | static void SelectEdge (const TopoDS_Shape& theS, |
105 | TopTools_ListOfShape& theLE) | |
7fd59977 | 106 | { |
9b7f3f83 | 107 | Standard_Real aT1, aT2, aDist, aDistMin; |
108 | TopExp_Explorer aExp; | |
109 | TopTools_ListIteratorOfListOfShape aIt; | |
110 | GeomAPI_ProjectPointOnCurve aProjPC; | |
111 | gp_Pnt aPE1, aPE2; | |
112 | TopoDS_Edge aRE; | |
113 | // | |
114 | aDistMin = RealLast(); | |
115 | // | |
116 | aIt.Initialize(theLE); | |
117 | for (; aIt.More(); aIt.Next()) { | |
118 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&aIt.Value(); | |
119 | // | |
120 | const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2); | |
121 | // | |
122 | aProjPC.Init(aC, aT1, aT2); | |
123 | aPE1 = aC->Value(aT1); | |
124 | aPE2 = aC->Value(aT2); | |
125 | // | |
126 | aDist = 0.; | |
127 | aExp.Init(theS, TopAbs_VERTEX); | |
128 | for (; aExp.More(); aExp.Next()) { | |
129 | const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExp.Current(); | |
130 | const gp_Pnt aP = BRep_Tool::Pnt(aV); | |
131 | // | |
132 | aProjPC.Perform(aP); | |
133 | if (aProjPC.NbPoints()) { | |
134 | aDist += aProjPC.LowerDistance(); | |
7fd59977 | 135 | } |
9b7f3f83 | 136 | else { |
137 | aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2)); | |
7fd59977 | 138 | } |
139 | } | |
9b7f3f83 | 140 | // |
141 | if (aDist < aDistMin) { | |
142 | aDistMin = aDist; | |
143 | aRE = aE; | |
7fd59977 | 144 | } |
7fd59977 | 145 | } |
9b7f3f83 | 146 | // |
147 | theLE.Clear(); | |
148 | theLE.Append(aRE); | |
7fd59977 | 149 | } |
150 | ||
7fd59977 | 151 | //======================================================================= |
152 | //function : CompletInt | |
153 | //purpose : | |
154 | //======================================================================= | |
155 | ||
156 | void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, | |
9b7f3f83 | 157 | const BRepAlgo_Image& InitOffsetFace) |
7fd59977 | 158 | { |
159 | //--------------------------------------------------------------- | |
0d969553 Y |
160 | // Calculate the intersections of offset faces |
161 | // Distinction of intersection between faces // tangents. | |
7fd59977 | 162 | //--------------------------------------------------------------- |
51740958 | 163 | TopoDS_Face F2; |
7fd59977 | 164 | TopTools_ListIteratorOfListOfShape it; |
165 | ||
166 | //--------------------------------------------------------------- | |
0d969553 | 167 | // Construction of bounding boxes |
7fd59977 | 168 | //--------------------------------------------------------------- |
169 | TopOpeBRepTool_BoxSort BOS; | |
170 | BRep_Builder B; | |
171 | TopoDS_Compound CompOS; | |
172 | B.MakeCompound(CompOS); | |
173 | ||
174 | for (it.Initialize(SetOfFaces); it.More(); it.Next()) { | |
175 | const TopoDS_Shape& OS = it.Value(); | |
176 | B.Add(CompOS,OS); | |
177 | } | |
178 | BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE); | |
179 | ||
180 | //--------------------------- | |
0d969553 | 181 | // Intersection of faces // |
7fd59977 | 182 | //--------------------------- |
183 | for (it.Initialize(SetOfFaces); it.More(); it.Next()) { | |
184 | const TopoDS_Face& F1 = TopoDS::Face(it.Value()); | |
185 | TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1); | |
186 | for (; itLI.More(); itLI.Next()) { | |
187 | F2 = TopoDS::Face(BOS.TouchedShape(itLI)); | |
188 | FaceInter(F1,F2,InitOffsetFace); | |
189 | } | |
190 | } | |
191 | } | |
192 | ||
193 | ||
194 | //======================================================================= | |
195 | //function : CompletInt | |
196 | //purpose : | |
197 | //======================================================================= | |
198 | ||
199 | void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1, | |
9b7f3f83 | 200 | const TopoDS_Face& F2, |
201 | const BRepAlgo_Image& InitOffsetFace) | |
7fd59977 | 202 | { |
203 | TopTools_ListOfShape LInt1, LInt2; | |
204 | TopoDS_Edge NullEdge; | |
205 | ||
206 | if (F1.IsSame(F2)) return; | |
207 | if (IsDone(F1,F2)) return; | |
208 | const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1); | |
209 | const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2); | |
210 | Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE && | |
9b7f3f83 | 211 | InitF1.ShapeType() == TopAbs_EDGE ); |
7fd59977 | 212 | Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE && |
9b7f3f83 | 213 | InitF2.ShapeType() == TopAbs_FACE); |
7fd59977 | 214 | TopTools_ListOfShape LE,LV; |
215 | LInt1.Clear(); LInt2.Clear(); | |
fe1d4d6c | 216 | if (BRepOffset_Tool::FindCommonShapes(F1,F2,LE,LV) || |
7fd59977 | 217 | myAsDes->HasCommonDescendant(F1,F2,LE)) { |
218 | //------------------------------------------------- | |
0d969553 | 219 | // F1 and F2 share shapes. |
7fd59977 | 220 | //------------------------------------------------- |
221 | if ( LE.IsEmpty() && !LV.IsEmpty()) { | |
222 | if (InterPipes) { | |
9b7f3f83 | 223 | //---------------------- |
224 | // tubes share a vertex. | |
225 | //---------------------- | |
226 | const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1); | |
227 | const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2); | |
228 | TopoDS_Vertex VE1[2],VE2[2]; | |
229 | TopExp::Vertices(EE1,VE1[0],VE1[1]); | |
230 | TopExp::Vertices(EE2,VE2[0],VE2[1]); | |
231 | TopoDS_Vertex V; | |
232 | for (Standard_Integer i = 0 ; i < 2; i++) { | |
233 | for (Standard_Integer j = 0 ; j < 2; j++) { | |
234 | if (VE1[i].IsSame(VE2[j])) { | |
235 | V = VE1[i]; | |
236 | } | |
237 | } | |
238 | } | |
239 | if (!InitOffsetFace.HasImage(V)) { //no sphere | |
240 | BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide); | |
241 | } | |
7fd59977 | 242 | } |
243 | else { | |
9b7f3f83 | 244 | //-------------------------------------------------------- |
245 | // Intersection having only common vertices | |
246 | // and supports having common edges. | |
247 | // UNSUFFICIENT, but a larger criterion shakes too | |
248 | // many sections. | |
249 | //-------------------------------------------------------- | |
250 | if (InterFaces) { | |
fe1d4d6c | 251 | if (BRepOffset_Tool::FindCommonShapes(TopoDS::Face(InitF1), |
252 | TopoDS::Face(InitF2),LE,LV)) { | |
9b7f3f83 | 253 | if (!LE.IsEmpty()) { |
254 | BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); | |
255 | } | |
256 | } | |
257 | else { | |
258 | BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge); | |
259 | } | |
260 | } | |
7fd59977 | 261 | } |
262 | } | |
263 | } | |
264 | else { | |
265 | if (InterPipes) { | |
266 | BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide); | |
267 | } | |
268 | else { | |
269 | BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); | |
270 | } | |
271 | } | |
272 | Store (F1,F2,LInt1,LInt2); | |
273 | } | |
274 | ||
275 | ||
276 | //======================================================================= | |
277 | //function : ConnexIntByArc | |
278 | //purpose : | |
279 | //======================================================================= | |
280 | ||
35e08fe8 | 281 | void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces*/, |
282 | const TopoDS_Shape& ShapeInit, | |
283 | const BRepOffset_Analyse& Analyse, | |
284 | const BRepAlgo_Image& InitOffsetFace) | |
7fd59977 | 285 | { |
286 | BRepOffset_Type OT = BRepOffset_Concave; | |
287 | if (mySide == TopAbs_OUT) OT = BRepOffset_Convex; | |
288 | TopExp_Explorer Exp(ShapeInit,TopAbs_EDGE); | |
289 | TopTools_ListOfShape LInt1,LInt2; | |
290 | TopoDS_Face F1,F2; | |
291 | TopoDS_Edge NullEdge; | |
292 | ||
293 | //--------------------------------------------------------------------- | |
0d969553 Y |
294 | // etape 1 : Intersection of faces // corresponding to the initial faces |
295 | // separated by a concave edge if offset > 0, otherwise convex. | |
7fd59977 | 296 | //--------------------------------------------------------------------- |
297 | for (; Exp.More(); Exp.Next()) { | |
298 | const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); | |
299 | const BRepOffset_ListOfInterval& L = Analyse.Type(E); | |
300 | if (!L.IsEmpty() && L.First().Type() == OT) { | |
301 | //----------------------------------------------------------- | |
0d969553 | 302 | // edge is of the proper type , return adjacent faces. |
7fd59977 | 303 | //----------------------------------------------------------- |
304 | const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); | |
305 | if (Anc.Extent() == 2) { | |
9b7f3f83 | 306 | F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First()); |
307 | F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First()); | |
308 | if (!IsDone(F1,F2)) { | |
309 | BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True); | |
310 | Store (F1,F2,LInt1,LInt2); | |
311 | } | |
312 | } | |
7fd59977 | 313 | } |
314 | } | |
315 | //--------------------------------------------------------------------- | |
0d969553 Y |
316 | // etape 2 : Intersections of tubes sharing a vertex without sphere with: |
317 | // - tubes on each other edge sharing the vertex | |
318 | // - faces containing an edge connected to vertex that has no tubes. | |
7fd59977 | 319 | //--------------------------------------------------------------------- |
320 | TopoDS_Vertex V[2]; | |
321 | TopTools_ListIteratorOfListOfShape it; | |
322 | ||
323 | for (Exp.Init(ShapeInit,TopAbs_EDGE); Exp.More(); Exp.Next()) { | |
324 | const TopoDS_Edge& E1 = TopoDS::Edge(Exp.Current()); | |
325 | if (InitOffsetFace.HasImage(E1)) { | |
326 | //--------------------------- | |
0d969553 | 327 | // E1 generated a tube. |
7fd59977 | 328 | //--------------------------- |
329 | F1 = TopoDS::Face(InitOffsetFace.Image(E1).First());; | |
330 | TopExp::Vertices(E1,V[0],V[1]); | |
331 | const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1); | |
332 | ||
333 | for (Standard_Integer i = 0; i < 2; i++) { | |
9b7f3f83 | 334 | if (!InitOffsetFace.HasImage(V[i])) { |
335 | //----------------------------- | |
336 | // the vertex has no sphere. | |
337 | //----------------------------- | |
338 | const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]); | |
339 | TopTools_ListOfShape TangOnV; | |
340 | Analyse.TangentEdges(E1,V[i],TangOnV); | |
341 | TopTools_MapOfShape MTEV; | |
342 | for (it.Initialize(TangOnV); it.More(); it.Next()) { | |
343 | MTEV.Add(it.Value()); | |
344 | } | |
345 | for (it.Initialize(Anc); it.More(); it.Next()) { | |
346 | const TopoDS_Edge& E2 = TopoDS::Edge(it.Value()); | |
7fd59977 | 347 | // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin |
9b7f3f83 | 348 | // if (E1.IsSame(E2) || MTEV.Contains(E2)) continue; |
349 | Standard_Boolean isToSkip = Standard_False; | |
7fd59977 | 350 | |
9b7f3f83 | 351 | if (!E1.IsSame(E2)) { |
352 | const BRepOffset_ListOfInterval& aL = Analyse.Type(E2); | |
7fd59977 | 353 | |
9b7f3f83 | 354 | isToSkip = (MTEV.Contains(E2) && |
355 | (aL.IsEmpty() || | |
356 | (!aL.IsEmpty() && aL.First().Type() != OT))); | |
357 | } | |
7fd59977 | 358 | |
9b7f3f83 | 359 | if (E1.IsSame(E2) || isToSkip) |
360 | continue; | |
7fd59977 | 361 | // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End |
9b7f3f83 | 362 | if (InitOffsetFace.HasImage(E2)) { |
363 | //----------------------------- | |
364 | // E2 generated a tube. | |
365 | //----------------------------- | |
366 | F2 = TopoDS::Face(InitOffsetFace.Image(E2).First()); | |
367 | if (!IsDone(F1,F2)) { | |
368 | //--------------------------------------------------------------------- | |
369 | // Intersection tube/tube if the edges are not tangent (AFINIR). | |
370 | //---------------------------------------------------------------------- | |
371 | BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide); | |
372 | Store (F1,F2,LInt1,LInt2); | |
373 | } | |
374 | } | |
375 | else { | |
376 | //------------------------------------------------------- | |
377 | // Intersection of the tube of E1 with faces // | |
378 | // to face containing E2 if they are not tangent | |
379 | // to the tube or if E2 is not a tangent edge. | |
380 | //------------------------------------------------------- | |
381 | const BRepOffset_ListOfInterval& L = Analyse.Type(E2); | |
382 | if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) { | |
383 | continue; | |
384 | } | |
385 | const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2); | |
386 | Standard_Boolean TangentFaces = Standard_False; | |
387 | if (AncE2.Extent() == 2) { | |
388 | TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ()); | |
389 | TangentFaces = (InitF2.IsSame(AncE1.First()) || | |
390 | InitF2.IsSame(AncE1.Last())); | |
391 | if (!TangentFaces) { | |
392 | F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First()); | |
393 | if (!IsDone(F1,F2)) { | |
394 | BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); | |
395 | Store (F1,F2,LInt1,LInt2); | |
396 | } | |
397 | } | |
398 | InitF2 = TopoDS::Face(AncE2.Last ()); | |
399 | TangentFaces = (InitF2.IsSame(AncE1.First()) || | |
400 | InitF2.IsSame(AncE1.Last())); | |
401 | if (!TangentFaces) { | |
402 | F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First()); | |
403 | if (!IsDone(F1,F2)) { | |
404 | BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); | |
405 | Store (F1,F2,LInt1,LInt2); | |
406 | } | |
407 | } | |
408 | } | |
409 | } | |
410 | } | |
411 | } | |
7fd59977 | 412 | } |
413 | } | |
414 | } | |
415 | } | |
416 | ||
417 | ||
418 | //======================================================================= | |
419 | //function : ConnexIntByInt | |
420 | //purpose : | |
421 | //======================================================================= | |
422 | ||
423 | void BRepOffset_Inter3d::ConnexIntByInt | |
424 | (const TopoDS_Shape& SI, | |
425 | const BRepOffset_DataMapOfShapeOffset& MapSF, | |
426 | const BRepOffset_Analyse& Analyse, | |
427 | TopTools_DataMapOfShapeShape& MES, | |
428 | TopTools_DataMapOfShapeShape& Build, | |
9b7f3f83 | 429 | TopTools_ListOfShape& Failed, |
430 | const Standard_Boolean bIsPlanar) | |
7fd59977 | 431 | { |
432 | //TopExp_Explorer Exp(SI,TopAbs_EDGE); | |
9b7f3f83 | 433 | TopTools_IndexedMapOfShape VEmap; |
434 | TopTools_IndexedDataMapOfShapeListOfShape aMVF; | |
7fd59977 | 435 | TopoDS_Face F1,F2,OF1,OF2,NF1,NF2; |
436 | TopAbs_State CurSide = mySide; | |
437 | BRep_Builder B; | |
9b7f3f83 | 438 | Standard_Boolean bEdge; |
439 | Standard_Integer i, aNb; | |
440 | TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2; | |
441 | // | |
442 | TopExp::MapShapes(SI, TopAbs_EDGE , VEmap); | |
443 | // map the shape for vertices | |
444 | if (bIsPlanar) { | |
445 | TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap); | |
b443d536 | 446 | // |
447 | // make vertex-faces connexity map with unique ancestors | |
448 | // TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF); | |
449 | TopExp_Explorer aExpF(SI, TopAbs_FACE); | |
450 | for (; aExpF.More(); aExpF.Next()) { | |
451 | const TopoDS_Shape& aF = aExpF.Current(); | |
452 | // | |
453 | TopExp_Explorer aExpV(aF, TopAbs_VERTEX); | |
454 | for (; aExpV.More(); aExpV.Next()) { | |
455 | const TopoDS_Shape& aV = aExpV.Current(); | |
456 | // | |
457 | TopTools_ListOfShape *pLF = aMVF.ChangeSeek(aV); | |
458 | if (!pLF) { | |
459 | pLF = &aMVF(aMVF.Add(aV, TopTools_ListOfShape())); | |
460 | pLF->Append(aF); | |
461 | continue; | |
462 | } | |
463 | // | |
464 | TopTools_ListIteratorOfListOfShape aItLF(*pLF); | |
465 | for (; aItLF.More(); aItLF.Next()) { | |
466 | if (aItLF.Value().IsSame(aF)) { | |
467 | break; | |
468 | } | |
469 | } | |
470 | if (!aItLF.More()) { | |
471 | pLF->Append(aF); | |
472 | } | |
473 | } | |
474 | } | |
9b7f3f83 | 475 | } |
476 | // | |
c2bf27a6 | 477 | TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2, aDMIntFF; |
478 | TopTools_IndexedDataMapOfShapeListOfShape aDMIntE; | |
ecf4f17c | 479 | // |
480 | if (bIsPlanar) { | |
481 | aNb = VEmap.Extent(); | |
482 | for (i = 1; i <= aNb; ++i) { | |
483 | const TopoDS_Shape& aS = VEmap(i); | |
484 | if (aS.ShapeType() != TopAbs_VERTEX) { | |
9b7f3f83 | 485 | continue; |
486 | } | |
487 | // | |
9b7f3f83 | 488 | // faces connected by the vertex |
489 | const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS); | |
490 | if (aLF.Extent() < 2) { | |
491 | continue; | |
492 | } | |
b443d536 | 493 | // build lists of faces connected to the same vertex by looking for |
494 | // the pairs in which the vertex is alone (not connected to shared edges) | |
ecf4f17c | 495 | TopTools_ListOfShape aLF1, aLF2; |
9b7f3f83 | 496 | // |
497 | it.Initialize(aLF); | |
498 | for (; it.More(); it.Next()) { | |
b443d536 | 499 | const TopoDS_Shape& aFV1 = it.Value(); |
9b7f3f83 | 500 | // |
b443d536 | 501 | // get edges of first face connected to current vertex |
9b7f3f83 | 502 | TopTools_MapOfShape aME; |
503 | TopExp_Explorer aExp(aFV1, TopAbs_EDGE); | |
504 | for (; aExp.More(); aExp.Next()) { | |
c2bf27a6 | 505 | const TopoDS_Shape& aE = aExp.Current(); |
506 | TopoDS_Iterator aItV(aE); | |
507 | for (; aItV.More(); aItV.Next()) { | |
508 | if (aS.IsSame(aItV.Value())) { | |
509 | aME.Add(aE); | |
510 | break; | |
511 | } | |
512 | } | |
9b7f3f83 | 513 | } |
514 | // | |
b443d536 | 515 | // get to the next face in the list |
516 | it1 = it; | |
9b7f3f83 | 517 | for (it1.Next(); it1.More(); it1.Next()) { |
b443d536 | 518 | const TopoDS_Shape& aFV2 = it1.Value(); |
9b7f3f83 | 519 | // |
9b7f3f83 | 520 | aExp.Init(aFV2, TopAbs_EDGE); |
521 | for (; aExp.More(); aExp.Next()) { | |
522 | const TopoDS_Shape& aEV2 = aExp.Current(); | |
523 | if (aME.Contains(aEV2)) { | |
9b7f3f83 | 524 | break; |
525 | } | |
526 | } | |
527 | // | |
b443d536 | 528 | if (!aExp.More()) { |
529 | // faces share only vertex - make pair for intersection | |
9b7f3f83 | 530 | aLF1.Append(aFV1); |
531 | aLF2.Append(aFV2); | |
9b7f3f83 | 532 | } |
533 | } | |
534 | } | |
535 | // | |
b443d536 | 536 | if (aLF1.Extent()) { |
537 | aDMVLF1.Bind(aS, aLF1); | |
538 | aDMVLF2.Bind(aS, aLF2); | |
9b7f3f83 | 539 | } |
ecf4f17c | 540 | } |
541 | } | |
542 | // | |
543 | aNb = VEmap.Extent(); | |
544 | for (i = 1; i <= aNb; ++i) { | |
545 | const TopoDS_Shape& aS = VEmap(i); | |
546 | // | |
547 | TopoDS_Edge E; | |
548 | TopTools_ListOfShape aLF1, aLF2; | |
549 | // | |
550 | bEdge = (aS.ShapeType() == TopAbs_EDGE); | |
551 | if (bEdge) { | |
552 | // faces connected by the edge | |
553 | E = *(TopoDS_Edge*)&aS; | |
554 | // | |
555 | const BRepOffset_ListOfInterval& L = Analyse.Type(E); | |
556 | if (L.IsEmpty()) { | |
557 | continue; | |
558 | } | |
559 | // | |
560 | BRepOffset_Type OT = L.First().Type(); | |
561 | if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) { | |
562 | continue; | |
563 | } | |
564 | // | |
565 | if (OT == BRepOffset_Concave) CurSide = TopAbs_IN; | |
566 | else CurSide = TopAbs_OUT; | |
567 | //----------------------------------------------------------- | |
568 | // edge is of the proper type, return adjacent faces. | |
569 | //----------------------------------------------------------- | |
570 | const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); | |
571 | if (Anc.Extent() != 2) { | |
572 | continue; | |
573 | } | |
574 | // | |
575 | F1 = TopoDS::Face(Anc.First()); | |
576 | F2 = TopoDS::Face(Anc.Last ()); | |
577 | // | |
578 | aLF1.Append(F1); | |
579 | aLF2.Append(F2); | |
580 | } | |
581 | else { | |
582 | if (!aDMVLF1.IsBound(aS)) { | |
583 | continue; | |
584 | } | |
585 | // | |
586 | aLF1 = aDMVLF1.Find(aS); | |
587 | aLF2 = aDMVLF2.Find(aS); | |
588 | // | |
9b7f3f83 | 589 | CurSide = mySide; |
7fd59977 | 590 | } |
9b7f3f83 | 591 | // |
592 | itF1.Initialize(aLF1); | |
593 | itF2.Initialize(aLF2); | |
594 | for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) { | |
595 | F1 = TopoDS::Face(itF1.Value()); | |
596 | F2 = TopoDS::Face(itF2.Value()); | |
597 | // | |
598 | OF1 = TopoDS::Face(MapSF(F1).Face()); | |
599 | OF2 = TopoDS::Face(MapSF(F2).Face()); | |
600 | if (!MES.IsBound(OF1)) { | |
601 | Standard_Boolean enlargeU = Standard_True; | |
602 | Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; | |
603 | BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); | |
604 | BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); | |
605 | MES.Bind(OF1,NF1); | |
606 | } | |
607 | else { | |
608 | NF1 = TopoDS::Face(MES(OF1)); | |
609 | } | |
610 | // | |
611 | if (!MES.IsBound(OF2)) { | |
612 | Standard_Boolean enlargeU = Standard_True; | |
613 | Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; | |
614 | BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); | |
615 | BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); | |
616 | MES.Bind(OF2,NF2); | |
617 | } | |
618 | else { | |
619 | NF2 = TopoDS::Face(MES(OF2)); | |
620 | } | |
621 | // | |
622 | if (!IsDone(NF1,NF2)) { | |
623 | TopTools_ListOfShape LInt1,LInt2; | |
624 | BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge); | |
625 | if (LInt1.Extent() > 1) { | |
626 | // intersection is in seceral edges (free sewing) | |
627 | SelectEdge(aS, LInt1); | |
628 | SelectEdge(aS, LInt2); | |
629 | } | |
630 | SetDone(NF1,NF2); | |
631 | if (!LInt1.IsEmpty()) { | |
632 | Store (NF1,NF2,LInt1,LInt2); | |
633 | // | |
634 | TopoDS_Compound C; | |
635 | B.MakeCompound(C); | |
636 | // | |
637 | if (Build.IsBound(aS)) { | |
638 | const TopoDS_Shape& aSE = Build(aS); | |
639 | TopExp_Explorer aExp(aSE, TopAbs_EDGE); | |
640 | for (; aExp.More(); aExp.Next()) { | |
641 | const TopoDS_Shape& aNE = aExp.Current(); | |
642 | B.Add(C, aNE); | |
643 | } | |
644 | } | |
645 | // | |
646 | it.Initialize(LInt1); | |
647 | for (; it.More(); it.Next()) { | |
648 | const TopoDS_Shape& aNE = it.Value(); | |
649 | B.Add(C, aNE); | |
c2bf27a6 | 650 | // |
651 | // keep connection from new edge to shape from which it was created | |
652 | TopTools_ListOfShape *pLS = &aDMIntE(aDMIntE.Add(aNE, TopTools_ListOfShape())); | |
653 | pLS->Append(aS); | |
654 | // keep connection to faces created the edge as well | |
655 | TopTools_ListOfShape* pLFF = aDMIntFF.Bound(aNE, TopTools_ListOfShape()); | |
656 | pLFF->Append(F1); | |
657 | pLFF->Append(F2); | |
9b7f3f83 | 658 | } |
659 | // | |
660 | Build.Bind(aS,C); | |
661 | } | |
662 | else { | |
663 | Failed.Append(aS); | |
664 | } | |
665 | } else { // IsDone(NF1,NF2) | |
666 | // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin | |
667 | const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1); | |
668 | const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2); | |
669 | ||
670 | if (!aLInt1.IsEmpty()) { | |
671 | TopoDS_Compound C; | |
672 | B.MakeCompound(C); | |
673 | // | |
674 | if (Build.IsBound(aS)) { | |
675 | const TopoDS_Shape& aSE = Build(aS); | |
676 | TopExp_Explorer aExp(aSE, TopAbs_EDGE); | |
677 | for (; aExp.More(); aExp.Next()) { | |
678 | const TopoDS_Shape& aNE = aExp.Current(); | |
679 | B.Add(C, aNE); | |
680 | } | |
681 | } | |
682 | // | |
683 | for (it.Initialize(aLInt1) ; it.More(); it.Next()) { | |
684 | const TopoDS_Shape &anE1 = it.Value(); | |
685 | // | |
686 | for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) { | |
687 | const TopoDS_Shape &anE2 = it1.Value(); | |
ecf4f17c | 688 | if (anE1.IsSame(anE2)) { |
9b7f3f83 | 689 | B.Add(C, anE1); |
c2bf27a6 | 690 | // |
691 | TopTools_ListOfShape *pLS = aDMIntE.ChangeSeek(anE1); | |
692 | if (pLS) { | |
693 | pLS->Append(aS); | |
ecf4f17c | 694 | } |
695 | } | |
9b7f3f83 | 696 | } |
697 | } | |
698 | Build.Bind(aS,C); | |
699 | } | |
700 | else { | |
701 | Failed.Append(aS); | |
702 | } | |
703 | } | |
704 | } | |
705 | // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End | |
7fd59977 | 706 | } |
ecf4f17c | 707 | // |
c2bf27a6 | 708 | // create unique intersection for each localized shared part |
ecf4f17c | 709 | aNb = aDMIntE.Extent(); |
710 | for (i = 1; i <= aNb; ++i) { | |
c2bf27a6 | 711 | const TopTools_ListOfShape& aLS = aDMIntE(i); |
712 | if (aLS.Extent() < 2) { | |
ecf4f17c | 713 | continue; |
714 | } | |
715 | // | |
c2bf27a6 | 716 | // intersection edge |
717 | const TopoDS_Edge& aE = TopoDS::Edge(aDMIntE.FindKey(i)); | |
718 | // faces created the edge | |
719 | const TopTools_ListOfShape& aLFF = aDMIntFF.Find(aE); | |
720 | const TopoDS_Shape& aF1 = aLFF.First(); | |
721 | const TopoDS_Shape& aF2 = aLFF.Last(); | |
722 | ||
723 | // Build really localized blocks from the original shapes in <aLS>: | |
724 | // 1. Find edges from original faces connected to two or more shapes in <aLS>; | |
725 | // 2. Make connexity blocks from edges in <aLS> and found connection edges; | |
726 | // 3. Check if the vertices from <aLS> are not connected by these connection edges: | |
727 | // a. If so - add these vertices to Connexity Block containing the corresponding | |
728 | // connexity edge; | |
729 | // b. If not - add this vertex to list of connexity blocks | |
730 | // 4. Create unique intersection edge for each connexity block | |
731 | ||
732 | // list of vertices | |
733 | TopTools_ListOfShape aLV; | |
734 | // compound of edges to build connexity blocks | |
ecf4f17c | 735 | TopoDS_Compound aCE; |
736 | B.MakeCompound(aCE); | |
c2bf27a6 | 737 | TopTools_MapOfShape aMS; |
738 | TopTools_ListIteratorOfListOfShape aItLS(aLS); | |
739 | for (; aItLS.More(); aItLS.Next()) { | |
740 | const TopoDS_Shape& aS = aItLS.Value(); | |
741 | aMS.Add(aS); | |
742 | if (aS.ShapeType() == TopAbs_EDGE) { | |
743 | B.Add(aCE, aS); | |
744 | } | |
745 | else { | |
746 | aLV.Append(aS); | |
747 | } | |
748 | } | |
ecf4f17c | 749 | // |
c2bf27a6 | 750 | // look for additional edges to connect the shared parts |
751 | TopTools_MapOfShape aMEConnection; | |
752 | for (Standard_Integer j = 0; j < 2; ++j) { | |
753 | const TopoDS_Shape& aF = !j ? aF1 : aF2; | |
754 | // | |
755 | TopExp_Explorer aExp(aF, TopAbs_EDGE); | |
756 | for (; aExp.More(); aExp.Next()) { | |
757 | const TopoDS_Shape& aEF = aExp.Current(); | |
758 | if (aMS.Contains(aEF) || aMEConnection.Contains(aEF)) { | |
759 | continue; | |
760 | } | |
761 | // | |
762 | TopoDS_Vertex aV1, aV2; | |
763 | TopExp::Vertices(TopoDS::Edge(aEF), aV1, aV2); | |
764 | // | |
765 | // find parts to which the edge is connected | |
766 | Standard_Integer iCounter = 0; | |
767 | aItLS.Initialize(aLS); | |
768 | for (; aItLS.More(); aItLS.Next()) { | |
769 | const TopoDS_Shape& aS = aItLS.Value(); | |
770 | // iterator is not suitable here, because aS may be a vertex | |
771 | TopExp_Explorer aExpV(aS, TopAbs_VERTEX); | |
772 | for (; aExpV.More(); aExpV.Next()) { | |
773 | const TopoDS_Shape& aV = aExpV.Current(); | |
774 | if (aV.IsSame(aV1) || aV.IsSame(aV2)) { | |
775 | ++iCounter; | |
776 | break; | |
777 | } | |
778 | } | |
779 | } | |
780 | // | |
781 | if (iCounter >= 2) { | |
782 | B.Add(aCE, aEF); | |
783 | aMEConnection.Add(aEF); | |
784 | } | |
785 | } | |
ecf4f17c | 786 | } |
787 | // | |
788 | TopTools_ListOfShape aLCBE; | |
789 | BOPTools_AlgoTools::MakeConnexityBlocks(aCE, TopAbs_VERTEX, TopAbs_EDGE, aLCBE); | |
c2bf27a6 | 790 | // |
791 | // create connexity blocks for alone vertices | |
792 | TopTools_ListOfShape aLCBV; | |
793 | TopTools_ListIteratorOfListOfShape aItLV(aLV); | |
794 | for (; aItLV.More(); aItLV.Next()) { | |
795 | const TopoDS_Shape& aV = aItLV.Value(); | |
796 | // check if this vertex is contained in some connexity block of edges | |
797 | TopTools_ListIteratorOfListOfShape aItLCB(aLCBE); | |
798 | for (; aItLCB.More(); aItLCB.Next()) { | |
799 | TopoDS_Shape& aCB = aItLCB.ChangeValue(); | |
800 | TopExp_Explorer aExpV(aCB, TopAbs_VERTEX); | |
801 | for (; aExpV.More(); aExpV.Next()) { | |
802 | if (aV.IsSame(aExpV.Current())) { | |
803 | B.Add(aCB, aV); | |
804 | break; | |
805 | } | |
806 | } | |
807 | if (aExpV.More()) { | |
808 | break; | |
809 | } | |
810 | } | |
811 | // | |
812 | if (!aItLCB.More()) { | |
813 | TopoDS_Compound aCV; | |
814 | B.MakeCompound(aCV); | |
815 | B.Add(aCV, aV); | |
816 | aLCBV.Append(aCV); | |
817 | } | |
818 | } | |
819 | // | |
820 | aLCBE.Append(aLCBV); | |
821 | // | |
ecf4f17c | 822 | if (aLCBE.Extent() == 1) { |
823 | continue; | |
824 | } | |
825 | // | |
c2bf27a6 | 826 | const TopoDS_Shape& aNF1 = MES(MapSF(aF1).Face()); |
827 | const TopoDS_Shape& aNF2 = MES(MapSF(aF2).Face()); | |
ecf4f17c | 828 | // |
c2bf27a6 | 829 | TopTools_ListIteratorOfListOfShape aItLCB(aLCBE); |
830 | for (aItLCB.Next(); aItLCB.More(); aItLCB.Next()) { | |
ecf4f17c | 831 | // make new edge with different tedge instance |
832 | TopoDS_Edge aNewEdge; | |
833 | TopoDS_Vertex aV1, aV2; | |
834 | Standard_Real aT1, aT2; | |
835 | // | |
836 | TopExp::Vertices(aE, aV1, aV2); | |
837 | BRep_Tool::Range(aE, aT1, aT2); | |
838 | // | |
839 | BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aNewEdge); | |
840 | // | |
c2bf27a6 | 841 | myAsDes->Add(aNF1, aNewEdge); |
842 | myAsDes->Add(aNF2, aNewEdge); | |
ecf4f17c | 843 | // |
c2bf27a6 | 844 | const TopoDS_Shape& aCB = aItLCB.Value(); |
ecf4f17c | 845 | TopoDS_Iterator aItCB(aCB); |
846 | for (; aItCB.More(); aItCB.Next()) { | |
847 | const TopoDS_Shape& aS = aItCB.Value(); | |
c2bf27a6 | 848 | if (aMEConnection.Contains(aS)) { |
849 | continue; | |
850 | } | |
ecf4f17c | 851 | TopoDS_Shape& aCI = Build.ChangeFind(aS); |
852 | // | |
853 | TopoDS_Compound aNewCI; | |
854 | B.MakeCompound(aNewCI); | |
855 | TopExp_Explorer aExp(aCI, TopAbs_EDGE); | |
856 | for (; aExp.More(); aExp.Next()) { | |
857 | const TopoDS_Shape& aSx = aExp.Current(); | |
858 | if (!aSx.IsSame(aE)) { | |
859 | B.Add(aNewCI, aSx); | |
860 | } | |
861 | } | |
862 | B.Add(aNewCI, aNewEdge); | |
863 | aCI = aNewCI; | |
864 | } | |
865 | } | |
866 | } | |
7fd59977 | 867 | } |
868 | ||
869 | //======================================================================= | |
870 | //function : ContextIntByInt | |
871 | //purpose : | |
872 | //======================================================================= | |
873 | ||
874 | void BRepOffset_Inter3d::ContextIntByInt | |
975ec82a J |
875 | (const TopTools_IndexedMapOfShape& ContextFaces, |
876 | const Standard_Boolean ExtentContext, | |
7fd59977 | 877 | const BRepOffset_DataMapOfShapeOffset& MapSF, |
878 | const BRepOffset_Analyse& Analyse, | |
879 | TopTools_DataMapOfShapeShape& MES, | |
880 | TopTools_DataMapOfShapeShape& Build, | |
9b7f3f83 | 881 | TopTools_ListOfShape& Failed, |
882 | const Standard_Boolean bIsPlanar) | |
7fd59977 | 883 | { |
7fd59977 | 884 | TopTools_MapOfShape MV; |
885 | TopExp_Explorer exp; | |
886 | TopoDS_Face OF,NF,WCF; | |
887 | TopoDS_Edge OE; | |
888 | TopoDS_Compound C; | |
889 | BRep_Builder B; | |
9b7f3f83 | 890 | TopTools_ListIteratorOfListOfShape it, itF; |
891 | Standard_Integer i, j, aNb, aNbVE; | |
892 | Standard_Boolean bEdge; | |
893 | ||
894 | aNb = ContextFaces.Extent(); | |
895 | for (i = 1; i <= aNb; i++) { | |
975ec82a | 896 | const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); |
7fd59977 | 897 | myTouched.Add(CF); |
898 | if (ExtentContext) { | |
899 | BRepOffset_Tool::EnLargeFace(CF,NF,0,0); | |
900 | MES.Bind(CF,NF); | |
901 | } | |
902 | } | |
903 | TopAbs_State Side = TopAbs_OUT; | |
904 | ||
9b7f3f83 | 905 | for (i = 1; i <= aNb; i++) { |
975ec82a | 906 | const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); |
7fd59977 | 907 | if (ExtentContext) WCF = TopoDS::Face(MES(CF)); |
908 | else WCF = CF; | |
909 | ||
9b7f3f83 | 910 | TopTools_IndexedMapOfShape VEmap; |
911 | TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); | |
912 | // | |
913 | if (bIsPlanar) { | |
914 | TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); | |
915 | } | |
916 | // | |
917 | aNbVE = VEmap.Extent(); | |
918 | for (j = 1; j <= aNbVE; ++j) { | |
919 | const TopoDS_Shape& aS = VEmap(j); | |
920 | // | |
921 | bEdge = (aS.ShapeType() == TopAbs_EDGE); | |
922 | // | |
923 | TopoDS_Edge E; | |
924 | TopTools_ListOfShape Anc; | |
925 | // | |
926 | if (bEdge) { | |
927 | // faces connected by the edge | |
928 | // | |
929 | E = *(TopoDS_Edge*)&aS; | |
930 | if (!Analyse.HasAncestor(E)) { | |
931 | //---------------------------------------------------------------- | |
932 | // the edges of faces of context that are not in the initial shape | |
933 | // can appear in the result. | |
934 | //---------------------------------------------------------------- | |
935 | if (!ExtentContext) { | |
936 | myAsDes->Add(CF,E); | |
937 | myNewEdges.Add(E); | |
938 | } | |
939 | else { | |
940 | if (!MES.IsBound(E)) { | |
941 | TopoDS_Edge NE; | |
942 | Standard_Real f,l,Tol; | |
943 | BRep_Tool::Range(E,f,l); | |
944 | Tol = BRep_Tool::Tolerance(E); | |
945 | ExtentEdge(CF,E,NE); | |
946 | TopoDS_Vertex V1,V2; | |
947 | TopExp::Vertices(E,V1,V2); | |
948 | NE.Orientation(TopAbs_FORWARD); | |
949 | myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); | |
950 | myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); | |
951 | TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); | |
952 | B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); | |
953 | aLocalShape = V2.Oriented(TopAbs_INTERNAL); | |
954 | B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); | |
955 | // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); | |
956 | // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); | |
957 | NE.Orientation(E.Orientation()); | |
958 | myAsDes->Add(CF,NE); | |
959 | myNewEdges.Add(NE); | |
960 | MES.Bind(E,NE); | |
961 | } | |
962 | else { | |
963 | TopoDS_Shape NE = MES(E); | |
964 | TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation()); | |
965 | myAsDes->Add(CF,aLocalShape); | |
966 | // myAsDes->Add(CF,NE.Oriented(E.Orientation())); | |
967 | } | |
968 | } | |
969 | continue; | |
970 | } | |
971 | Anc = Analyse.Ancestors(E); | |
7fd59977 | 972 | } |
973 | else { | |
9b7f3f83 | 974 | // faces connected by the vertex |
975 | // | |
976 | if (!Analyse.HasAncestor(aS)) { | |
977 | continue; | |
978 | } | |
979 | // | |
980 | const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS); | |
981 | it.Initialize(aLE); | |
982 | for (; it.More(); it.Next()) { | |
983 | const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value(); | |
984 | // | |
985 | if (BRep_Tool::Degenerated(aE)) { | |
986 | continue; | |
987 | } | |
988 | // | |
989 | if (VEmap.Contains(aE)) { | |
990 | continue; | |
991 | } | |
992 | // | |
993 | const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE); | |
994 | itF.Initialize(aLF); | |
995 | for (; itF.More(); itF.Next()) { | |
996 | const TopoDS_Shape& aF = itF.Value(); | |
997 | Standard_Boolean bAdd = Standard_True; | |
998 | exp.Init(aF, TopAbs_EDGE); | |
999 | for (; exp.More() && bAdd; exp.Next()) { | |
1000 | const TopoDS_Shape& aEF = exp.Current(); | |
1001 | bAdd = !VEmap.Contains(aEF); | |
1002 | } | |
1003 | if (bAdd) { | |
1004 | Anc.Append(aF); | |
1005 | } | |
1006 | } | |
1007 | } | |
7fd59977 | 1008 | } |
9b7f3f83 | 1009 | // |
1010 | itF.Initialize(Anc); | |
1011 | for (; itF.More(); itF.Next()) { | |
1012 | const TopoDS_Face& F = TopoDS::Face(itF.Value()); | |
1013 | OF = TopoDS::Face(MapSF(F).Face()); | |
1014 | TopoDS_Shape aLocalShape = MapSF(F).Generated(E); | |
1015 | OE = TopoDS::Edge(aLocalShape); | |
1016 | // OE = TopoDS::Edge(MapSF(F).Generated(E)); | |
1017 | if (!MES.IsBound(OF)) { | |
1018 | BRepOffset_Tool::EnLargeFace(OF,NF,1,1); | |
1019 | MES.Bind(OF,NF); | |
1020 | } | |
1021 | else { | |
1022 | NF = TopoDS::Face(MES(OF)); | |
1023 | } | |
1024 | if (!IsDone(NF,CF)) { | |
1025 | TopTools_ListOfShape LInt1,LInt2; | |
1026 | TopTools_ListOfShape LOE; | |
1027 | LOE.Append(OE); | |
1028 | BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge); | |
1029 | SetDone(NF,CF); | |
1030 | if (!LInt1.IsEmpty()) { | |
1031 | Store (CF,NF,LInt1,LInt2); | |
1032 | if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) { | |
1033 | Build.Bind(aS,LInt1.First()); | |
1034 | } | |
1035 | else { | |
1036 | B.MakeCompound(C); | |
1037 | if (Build.IsBound(aS)) { | |
1038 | const TopoDS_Shape& aSE = Build(aS); | |
1039 | exp.Init(aSE, TopAbs_EDGE); | |
1040 | for (; exp.More(); exp.Next()) { | |
1041 | const TopoDS_Shape& aNE = exp.Current(); | |
1042 | B.Add(C, aNE); | |
1043 | } | |
1044 | } | |
1045 | // | |
1046 | for (it.Initialize(LInt1) ; it.More(); it.Next()) { | |
1047 | B.Add(C,it.Value()); | |
1048 | } | |
1049 | Build.Bind(aS,C); | |
1050 | } | |
1051 | } | |
1052 | else { | |
1053 | Failed.Append(aS); | |
1054 | } | |
1055 | } | |
7fd59977 | 1056 | } |
1057 | } | |
1058 | } | |
1059 | } | |
1060 | ||
1061 | //======================================================================= | |
1062 | //function : ContextIntByArc | |
1063 | //purpose : | |
1064 | //======================================================================= | |
1065 | ||
975ec82a | 1066 | void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces, |
9b7f3f83 | 1067 | const Standard_Boolean InSide, |
1068 | const BRepOffset_Analyse& Analyse, | |
1069 | const BRepAlgo_Image& InitOffsetFace, | |
1070 | BRepAlgo_Image& InitOffsetEdge) | |
7fd59977 | 1071 | |
1072 | { | |
1073 | TopTools_ListOfShape LInt1,LInt2; | |
7fd59977 | 1074 | TopTools_MapOfShape MV; |
1075 | TopExp_Explorer exp; | |
1076 | TopoDS_Face OF1,OF2; | |
1077 | TopoDS_Edge OE; | |
1078 | BRep_Builder B; | |
1079 | TopoDS_Edge NullEdge; | |
975ec82a | 1080 | Standard_Integer j; |
7fd59977 | 1081 | |
975ec82a J |
1082 | for (j = 1; j <= ContextFaces.Extent(); j++) { |
1083 | const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j)); | |
7fd59977 | 1084 | myTouched.Add(CF); |
1085 | } | |
1086 | ||
975ec82a J |
1087 | for (j = 1; j <= ContextFaces.Extent(); j++) { |
1088 | const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j)); | |
7fd59977 | 1089 | for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
9b7f3f83 | 1090 | exp.More(); exp.Next()) { |
7fd59977 | 1091 | const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); |
1092 | if (!Analyse.HasAncestor(E)) { | |
9b7f3f83 | 1093 | if (InSide) |
1094 | myAsDes->Add(CF,E); | |
1095 | else { | |
1096 | TopoDS_Edge NE; | |
1097 | if (!InitOffsetEdge.HasImage(E)) { | |
1098 | Standard_Real f,l,Tol; | |
1099 | BRep_Tool::Range(E,f,l); | |
1100 | Tol = BRep_Tool::Tolerance(E); | |
1101 | ExtentEdge(CF,E,NE); | |
1102 | TopoDS_Vertex V1,V2; | |
1103 | TopExp::Vertices(E,V1,V2); | |
1104 | NE.Orientation(TopAbs_FORWARD); | |
1105 | myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); | |
1106 | myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); | |
1107 | TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); | |
1108 | B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); | |
1109 | aLocalShape = V2.Oriented(TopAbs_INTERNAL); | |
1110 | B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); | |
1111 | // B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); | |
1112 | // B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); | |
1113 | NE.Orientation(E.Orientation()); | |
1114 | myAsDes->Add(CF,NE); | |
1115 | InitOffsetEdge.Bind(E,NE); | |
1116 | } | |
1117 | else { | |
1118 | NE = TopoDS::Edge(InitOffsetEdge.Image(E).First()); | |
1119 | myAsDes->Add(CF,NE.Oriented(E.Orientation())); | |
1120 | } | |
1121 | } | |
1122 | continue; | |
7fd59977 | 1123 | } |
1124 | OE.Nullify(); | |
0d969553 Y |
1125 | //--------------------------------------------------- |
1126 | // OF1 parallel facee generated by the ancestor of E. | |
1127 | //--------------------------------------------------- | |
7fd59977 | 1128 | const TopoDS_Shape SI = Analyse.Ancestors(E).First(); |
1129 | OF1 = TopoDS::Face(InitOffsetFace.Image(SI).First()); | |
3d58dc49 | 1130 | OE = TopoDS::Edge(InitOffsetEdge.Image(E).First()); |
1131 | ||
1132 | { | |
1133 | //Check if OE has pcurve in CF | |
1134 | ||
1135 | Standard_Real f,l; | |
1136 | ||
1137 | Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l); | |
1138 | Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); | |
1139 | ||
1140 | if(C1.IsNull() || C2.IsNull()) | |
1141 | { | |
1142 | continue; | |
1143 | } | |
1144 | } | |
1145 | ||
7fd59977 | 1146 | //-------------------------------------------------- |
0d969553 | 1147 | // MAJ of OE on cap CF. |
7fd59977 | 1148 | //-------------------------------------------------- |
9b7f3f83 | 1149 | // TopTools_ListOfShape LOE; LOE.Append(OE); |
7fd59977 | 1150 | // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide); |
1151 | // LInt2.Clear(); | |
1152 | // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes, | |
9b7f3f83 | 1153 | // LInt1,LInt2); |
7fd59977 | 1154 | LInt1.Clear(); LInt1.Append(OE); |
1155 | LInt2.Clear(); | |
9b7f3f83 | 1156 | TopAbs_Orientation anOri1, anOri2; |
1157 | BRepOffset_Tool::OrientSection(OE,CF,OF1, anOri1,anOri2); | |
1158 | // if (mySide == TopAbs_OUT); | |
1159 | anOri1 = TopAbs::Reverse(anOri1); | |
1160 | LInt1.First().Orientation(anOri1); | |
7fd59977 | 1161 | Store(CF,OF1,LInt1,LInt2); |
1162 | ||
1163 | //------------------------------------------------------ | |
0d969553 | 1164 | // Processing of offsets on the ancestors of vertices. |
7fd59977 | 1165 | //------------------------------------------------------ |
1166 | TopoDS_Vertex V[2]; | |
1167 | TopExp::Vertices (E,V[0],V[1]); | |
1168 | for (Standard_Integer i = 0; i < 2; i++) { | |
9b7f3f83 | 1169 | if (!MV.Add(V[i])) continue; |
1170 | OF1.Nullify(); | |
1171 | const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]); | |
1172 | TopTools_ListIteratorOfListOfShape itLE(LE); | |
1173 | for ( ; itLE.More(); itLE.Next()) { | |
1174 | const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value()); | |
1175 | if (InitOffsetFace.HasImage(EV)) { | |
1176 | //------------------------------------------------- | |
1177 | // OF1 parallel face generated by an ancester edge of V[i]. | |
1178 | //------------------------------------------------- | |
1179 | OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First()); | |
1180 | OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First()); | |
3d58dc49 | 1181 | |
1182 | { | |
1183 | //Check if OE has pcurve in CF and OF1 | |
1184 | ||
1185 | Standard_Real f,l; | |
1186 | ||
1187 | Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(OE,CF,f,l); | |
1188 | Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(OE,OF1,f,l); | |
1189 | ||
1190 | if(C1.IsNull() || C2.IsNull()) | |
1191 | { | |
1192 | continue; | |
1193 | } | |
1194 | } | |
1195 | ||
9b7f3f83 | 1196 | //-------------------------------------------------- |
1197 | // MAj of OE on cap CF. | |
1198 | //-------------------------------------------------- | |
1199 | // LOE.Clear(); LOE.Append(OE); | |
1200 | // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide); | |
1201 | // LInt2.Clear(); | |
1202 | // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes, | |
1203 | // LInt1,LInt2); | |
1204 | LInt1.Clear(); LInt1.Append(OE); | |
1205 | LInt2.Clear(); | |
1206 | TopAbs_Orientation O1,O2; | |
1207 | BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2); | |
1208 | // if (mySide == TopAbs_OUT); | |
1209 | O1 = TopAbs::Reverse(O1); | |
1210 | LInt1.First().Orientation(O1); | |
1211 | Store(CF,OF1,LInt1,LInt2); | |
1212 | } | |
1213 | } | |
7fd59977 | 1214 | } |
1215 | } | |
1216 | ||
1217 | for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); | |
9b7f3f83 | 1218 | exp.More(); exp.Next()) { |
7fd59977 | 1219 | const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); |
1220 | if (!Analyse.HasAncestor(V)) { | |
9b7f3f83 | 1221 | continue; |
7fd59977 | 1222 | } |
1223 | const TopTools_ListOfShape& LE = Analyse.Ancestors(V); | |
1224 | TopTools_ListIteratorOfListOfShape itLE(LE); | |
1225 | for (; itLE.More(); itLE.Next()) { | |
9b7f3f83 | 1226 | const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value()); |
1227 | const TopTools_ListOfShape& LF = Analyse.Ancestors(EV); | |
1228 | TopTools_ListIteratorOfListOfShape itLF(LF); | |
1229 | for ( ; itLF.More(); itLF.Next()) { | |
1230 | const TopoDS_Face& FEV = TopoDS::Face(itLF.Value()); | |
1231 | //------------------------------------------------- | |
1232 | // OF1 parallel face generated by uneFace ancestor of V[i]. | |
1233 | //------------------------------------------------- | |
1234 | OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First()); | |
1235 | if (!IsDone(OF1,CF)) { | |
1236 | //------------------------------------------------------- | |
1237 | // Find if one of edges of OF1 has no trace in CF. | |
1238 | //------------------------------------------------------- | |
1239 | TopTools_ListOfShape LOE; | |
1240 | TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE); | |
1241 | for ( ;exp2.More(); exp2.Next()) { | |
1242 | LOE.Append(exp2.Current()); | |
1243 | } | |
1244 | BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol); | |
1245 | //------------------------------------------------------- | |
1246 | // If no trace try intersection. | |
1247 | //------------------------------------------------------- | |
1248 | if (LInt1.IsEmpty()) { | |
1249 | BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge); | |
1250 | } | |
1251 | Store (CF,OF1,LInt1,LInt2); | |
1252 | } | |
1253 | } | |
7fd59977 | 1254 | } |
1255 | } | |
1256 | } | |
1257 | } | |
1258 | ||
1259 | //======================================================================= | |
1260 | //function : AddCommonEdges | |
1261 | //purpose : | |
1262 | //======================================================================= | |
1263 | ||
35e08fe8 | 1264 | void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape&) |
7fd59977 | 1265 | { |
1266 | } | |
1267 | ||
1268 | ||
1269 | //======================================================================= | |
1270 | //function : SetDone | |
1271 | //purpose : | |
1272 | //======================================================================= | |
1273 | ||
1274 | void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1, | |
9b7f3f83 | 1275 | const TopoDS_Face& F2) |
7fd59977 | 1276 | { |
1277 | if (!myDone.IsBound(F1)) { | |
1278 | TopTools_ListOfShape empty; | |
1279 | myDone.Bind(F1,empty); | |
1280 | } | |
1281 | myDone(F1).Append(F2); | |
1282 | if (!myDone.IsBound(F2)) { | |
1283 | TopTools_ListOfShape empty; | |
1284 | myDone.Bind(F2,empty); | |
1285 | } | |
1286 | myDone(F2).Append(F1); | |
1287 | } | |
1288 | ||
1289 | ||
1290 | //======================================================================= | |
1291 | //function : IsDone | |
1292 | //purpose : | |
1293 | //======================================================================= | |
1294 | ||
1295 | Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1, | |
9b7f3f83 | 1296 | const TopoDS_Face& F2) |
7fd59977 | 1297 | const |
1298 | { | |
1299 | if (myDone.IsBound(F1)) { | |
1300 | TopTools_ListIteratorOfListOfShape it (myDone(F1)); | |
1301 | for (; it.More(); it.Next()) { | |
1302 | if (it.Value().IsSame(F2)) return Standard_True; | |
1303 | } | |
1304 | } | |
1305 | return Standard_False; | |
1306 | } | |
1307 | ||
1308 | ||
1309 | //======================================================================= | |
1310 | //function : TouchedFaces | |
1311 | //purpose : | |
1312 | //======================================================================= | |
1313 | ||
975ec82a | 1314 | TopTools_IndexedMapOfShape& BRepOffset_Inter3d::TouchedFaces() |
7fd59977 | 1315 | { |
1316 | return myTouched; | |
1317 | } | |
1318 | ||
1319 | ||
1320 | //======================================================================= | |
1321 | //function : AsDes | |
1322 | //purpose : | |
1323 | //======================================================================= | |
1324 | ||
1325 | Handle(BRepAlgo_AsDes) BRepOffset_Inter3d::AsDes() const | |
1326 | { | |
1327 | return myAsDes; | |
1328 | } | |
1329 | ||
1330 | ||
1331 | //======================================================================= | |
1332 | //function : NewEdges | |
1333 | //purpose : | |
1334 | //======================================================================= | |
1335 | ||
975ec82a | 1336 | TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges() |
7fd59977 | 1337 | { |
1338 | return myNewEdges; | |
1339 | } | |
1340 | ||
1341 | ||
1342 | ||
1343 | //======================================================================= | |
1344 | //function : Store | |
1345 | //purpose : | |
1346 | //======================================================================= | |
1347 | ||
1348 | void BRepOffset_Inter3d::Store(const TopoDS_Face& F1, | |
9b7f3f83 | 1349 | const TopoDS_Face& F2, |
1350 | const TopTools_ListOfShape& LInt1, | |
1351 | const TopTools_ListOfShape& LInt2) | |
7fd59977 | 1352 | { |
1353 | if (!LInt1.IsEmpty()) { | |
1354 | myTouched.Add(F1); | |
1355 | myTouched.Add(F2); | |
1356 | myAsDes->Add( F1,LInt1); | |
1357 | myAsDes->Add( F2,LInt2); | |
1358 | TopTools_ListIteratorOfListOfShape it(LInt1); | |
1359 | for (; it.More(); it.Next()) { | |
1360 | myNewEdges.Add(it.Value()); | |
1361 | } | |
1362 | } | |
1363 | SetDone(F1,F2); | |
1364 | } |