1 // Created on: 1993-06-17
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
21 // modified by NIZNHY-PKV
23 #include <BOP_WireEdgeSet.ixx>
25 #include <Standard_ProgramError.hxx>
27 #include <Precision.hxx>
30 #include <gp_Vec2d.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <gp_Dir2d.hxx>
34 #include <Geom2d_Curve.hxx>
35 #include <Geom2d_Line.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom_Surface.hxx>
38 #include <GeomAbs_SurfaceType.hxx>
39 #include <GeomAbs_CurveType.hxx>
40 #include <GeomAPI_ProjectPointOnSurf.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRepAdaptor_Surface.hxx>
44 #include <BRepAdaptor_Curve.hxx>
48 #include <TopExp_Explorer.hxx>
50 #include <BOPTools_Tools2D.hxx>
52 // modified by NIZHNY-MKK Fri May 30 10:18:01 2003.BEGIN
53 #include <TopTools_IndexedMapOfShape.hxx>
55 #include <BOPTools_Tools3D.hxx>
57 static void GetOrientationVOnE(const TopoDS_Shape& V,
58 const TopoDS_Shape& E1,
59 const TopoDS_Shape& E2,
60 TopAbs_Orientation& o1,
61 TopAbs_Orientation& o2);
62 // modified by NIZHNY-MKK Fri May 30 10:18:03 2003.END
64 //=======================================================================
65 //function : BOP_WireEdgeSet::BOP_WireEdgeSet
67 //=======================================================================
68 BOP_WireEdgeSet::BOP_WireEdgeSet()
70 BOP_ShapeSet(TopAbs_VERTEX)
73 //=======================================================================
74 //function : BOP_WireEdgeSet::BOP_WireEdgeSet
76 //=======================================================================
77 BOP_WireEdgeSet::BOP_WireEdgeSet(const TopoDS_Face& F)
79 BOP_ShapeSet(TopAbs_VERTEX),
84 //=======================================================================
85 //function : Initialize
87 //=======================================================================
88 void BOP_WireEdgeSet::Initialize(const TopoDS_Face& F)
93 //=======================================================================
96 //=======================================================================
97 void BOP_WireEdgeSet::AddShape(const TopoDS_Shape& S)
102 //=======================================================================
103 //function : AddStartElement
105 //=======================================================================
106 void BOP_WireEdgeSet::AddStartElement(const TopoDS_Shape& S)
108 ProcessAddStartElement(S);
111 //=======================================================================
112 //function : AddElement
114 //=======================================================================
115 void BOP_WireEdgeSet::AddElement(const TopoDS_Shape& S)
117 BOP_ShapeSet::AddElement(S);
120 //=======================================================================
121 //function : InitNeighbours
123 //=======================================================================
124 void BOP_WireEdgeSet::InitNeighbours(const TopoDS_Shape& E)
126 mySubShapeExplorer.Init(E,mySubShapeType);
133 //=======================================================================
134 //function : FindNeighbours
136 //=======================================================================
137 void BOP_WireEdgeSet::FindNeighbours()
139 while (mySubShapeExplorer.More()) {
141 // l = list of edges neighbour of edge myCurrentShape trough
142 // the vertex mySubShapeExplorer.Current(), which is a vertex of the
143 // edge myCurrentShape.
144 const TopoDS_Shape& V = mySubShapeExplorer.Current();
146 const TopTools_ListOfShape & l =
147 MakeNeighboursList(myCurrentShape, V);
149 // myIncidentShapesIter iterates on the neighbour edges of the edge
150 // given as InitNeighbours() argument (this edge has been stored
151 // in the field myCurrentShape).
153 myIncidentShapesIter.Initialize(l);
154 if (myIncidentShapesIter.More()) {
158 mySubShapeExplorer.Next();
163 //=======================================================================
164 //function : MakeNeighboursList
165 //purpose : find edges connected to Earg by Varg
166 //=======================================================================
167 const TopTools_ListOfShape & BOP_WireEdgeSet::MakeNeighboursList(const TopoDS_Shape& Earg,
168 const TopoDS_Shape& Varg)
170 const TopoDS_Edge& E = TopoDS::Edge(Earg);
171 const TopoDS_Vertex& V = TopoDS::Vertex(Varg);
173 const TopTools_ListOfShape& l = mySubShapeMap.FindFromKey(Varg);
175 Standard_Integer nclosing = NbClosingShapes(l);
177 // build myCurrentShapeNeighbours =
178 // edge list made of connected shapes to Earg through Varg
179 myCurrentShapeNeighbours.Clear();
181 Standard_Integer iapp = 0;
182 for (TopTools_ListIteratorOfListOfShape it(l); it.More(); it.Next()) {
184 const TopoDS_Shape& curn = it.Value(); // current neighbour
185 Standard_Boolean k = VertexConnectsEdgesClosing(Varg, Earg, curn);
187 myCurrentShapeNeighbours.Append(curn);
191 Standard_Integer newn = NbClosingShapes(myCurrentShapeNeighbours);
194 const TopoDS_Face& F = myFace;
195 // several sewing edges connected to E by V such as :
196 // orientation of V in E # orientation of V in its edges.
197 // one leaves among the connected sewing edges,
198 // only edge A that checks tg(E) ^ tg(A) > 0
200 TopAbs_Orientation Eori;
201 gp_Vec2d d1E; gp_Pnt2d pE;
202 Standard_Real fiE, laE, tolpc, parE;
204 parE = BRep_Tool::Parameter(V,E);
206 Handle(Geom2d_Curve) PCE;
207 BOPTools_Tools2D::CurveOnSurface(E, F, PCE, fiE, laE, tolpc, Standard_False);
210 PCE->D1(parE, pE, d1E);
213 LocalD1 (F, E, V, pE, d1E);
216 Eori = E.Orientation();
217 if (Eori == TopAbs_REVERSED) {
221 TopTools_ListIteratorOfListOfShape lclo(myCurrentShapeNeighbours);
222 Standard_Integer rang = 0;
223 while (lclo.More()) {
226 if ( ! IsClosed(lclo.Value()) ) {
231 const TopoDS_Edge& EE = TopoDS::Edge(lclo.Value());
232 Standard_Real parEE, fiEE, laEE, tolpcc;
233 gp_Vec2d d1EE; gp_Pnt2d pEE;
235 parEE = BRep_Tool::Parameter(V,EE);
237 Handle(Geom2d_Curve) PCEE;
238 BOPTools_Tools2D::CurveOnSurface (EE, F, PCEE, fiEE, laEE, tolpcc, Standard_False);//
240 if (!PCEE.IsNull()) {
241 PCEE->D1(parEE,pEE,d1EE);
245 LocalD1(F, EE, V, pEE, d1EE);
248 TopAbs_Orientation EEori = EE.Orientation();
249 if (EEori == TopAbs_REVERSED) d1EE.Reverse();
251 Standard_Real cross = d1E.Crossed(d1EE);
252 TopAbs_Orientation oVE,oVEE;
254 // modified by NIZHNY-MKK Fri May 30 10:17:10 2003.BEGIN
255 GetOrientationVOnE(V,E,EE,oVE,oVEE);
256 // VertexConnectsEdges(V,E,EE,oVE,oVEE);
257 // modified by NIZHNY-MKK Fri May 30 10:17:13 2003.END
259 Standard_Boolean t2 = ( (cross > 0) && oVE == TopAbs_REVERSED ) ||
260 ( (cross < 0) && oVE == TopAbs_FORWARD );
263 // this is proper IsClosed, only it is preserved among IsClosed
267 // edge IsClosed is suspended
268 myCurrentShapeNeighbours.Remove(lclo);
270 }// end of while (lclo.More())
271 }// end of if (newn >= 2 )
272 return myCurrentShapeNeighbours;
273 }// end of if (nclosing)
278 } // MakeNeighoursList
280 //=======================================================================
281 //function : VertexConnectsEdges
283 //=======================================================================
284 Standard_Boolean BOP_WireEdgeSet::VertexConnectsEdges(const TopoDS_Shape& V,
285 const TopoDS_Shape& E1,
286 const TopoDS_Shape& E2,
287 TopAbs_Orientation& o1,
288 TopAbs_Orientation& o2) const
290 TopExp_Explorer ex1, ex2;
291 ex1.Init(E1,TopAbs_VERTEX);
292 for(; ex1.More(); ex1.Next()) {
294 if (V.IsSame(ex1.Current())) {
295 ex2.Init(E2,TopAbs_VERTEX);
296 for(; ex2.More(); ex2.Next()) {
298 if (V.IsSame(ex2.Current())) {
299 o1 = ex1.Current().Orientation();
300 o2 = ex2.Current().Orientation();
302 return Standard_True;
308 return Standard_False;
312 //=======================================================================
313 //function : VertexConnectEdgesClosing
315 //=======================================================================
316 Standard_Boolean BOP_WireEdgeSet::VertexConnectsEdgesClosing(const TopoDS_Shape& V,
317 const TopoDS_Shape& E1,
318 const TopoDS_Shape& E2) const
320 // Let S the set of incident edges on vertex V.
321 // S contains at least one closed edge on the periodic face to build.
322 // (the face implied in closing test of edge is myFace)
323 // E1,E2 are S shapes (sharing V).
325 // if E1 and E2 are not closed : edges are NOT connected
326 // if E1 or E2 is/are closed :
327 // if V changes of relative orientation between E1,E2 : edges are connected
328 // else : edges are NOT connected
330 // example with E1 NOT closed, E2 closed :
332 // E1 FORWARD, V REVERSED on E1
333 // E2 FORWARD, V FORWARD on E2 --> edges are connected
335 // E1 FORWARD, V REVERSED on E1
336 // E2 REVERSED, V FORWARD on E2 --> edges are NOT connected
337 //-----------------------------------------------------------------------
339 Standard_Boolean c1 = IsClosed(E1);
340 Standard_Boolean c2 = IsClosed(E2);
342 Standard_Boolean testconnect = c1 || c2;
343 Standard_Boolean resu = Standard_False;
344 TopAbs_Orientation o1,o2;
346 // SSCONNEX = False ==> E2 is selected to create as many
347 // (default) faces as there are components connected in UV.
348 // SSCONNEX = True ==> the entire edge E2 sharing V with E1 is taken
349 // so that orientation(V/E1) # orientation(V/E2)
350 // ==> face of part and other sewings
352 Standard_Boolean u1 = c1 ? IsUClosed(E1) : Standard_False;
353 Standard_Boolean v1 = c1 ? IsVClosed(E1) : Standard_False;
354 Standard_Boolean u2 = c2 ? IsUClosed(E2) : Standard_False;
355 Standard_Boolean v2 = c2 ? IsVClosed(E2) : Standard_False;
356 Standard_Boolean uvdiff = (u1 && v2) || (u2 && v1);
357 testconnect = uvdiff;
361 resu = VertexConnectsEdges(V,E1,E2,o1,o2);
364 // cto 012 O2 sewing edge of cylindric face
365 // chain of components split ON and OUT of the same orientation
366 TopAbs_Orientation oe1 = E1.Orientation();
367 TopAbs_Orientation oe2 = E2.Orientation();
368 Standard_Boolean iseq = E1.IsEqual(E2);
369 if ( (c1 && c2) && (oe1 == oe2) && (!iseq) ) {
370 resu = VertexConnectsEdges(V,E1,E2,o1,o2);
376 //=======================================================================
377 //function : NbClosingShapes
379 //=======================================================================
380 Standard_Integer BOP_WireEdgeSet::NbClosingShapes(const TopTools_ListOfShape & L) const
382 Standard_Integer n = 0;
383 TopTools_ListIteratorOfListOfShape it(L);
384 for ( ; it.More(); it.Next()) {
385 const TopoDS_Shape& S = it.Value();
393 //=======================================================================
396 //=======================================================================
397 void BOP_WireEdgeSet::LocalD1(const TopoDS_Face& F,
398 const TopoDS_Edge& E,
399 const TopoDS_Vertex& V,
404 Standard_Real parE, fiE, laE, u, v;
406 parE = BRep_Tool::Parameter(V,E);
408 Handle(Geom_Curve) CE = BRep_Tool::Curve(E, Loc, fiE, laE);
409 CE = Handle(Geom_Curve)::DownCast(CE->Transformed(Loc.Transformation()));
411 gp_Pnt p3dE; gp_Vec d3dE;
412 CE->D1(parE, p3dE, d3dE);
414 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
415 GeomAPI_ProjectPointOnSurf proj(p3dE,S);
417 proj.LowerDistanceParameters(u,v);
420 S->D1(u,v,bid,d1u,d1v);
426 //=======================================================================
427 //function : IsClosed
429 //=======================================================================
430 Standard_Boolean BOP_WireEdgeSet::IsClosed(const TopoDS_Shape& E) const
432 const TopoDS_Edge& EE = TopoDS::Edge(E);
433 Standard_Boolean closed = BRep_Tool::IsClosed(EE,myFace);
435 // modified by NIZHNY-MKK Wed May 12 15:44:10 2004.BEGIN
437 TopoDS_Edge aE1, aE2;
438 BOPTools_Tools3D::GetSeam (myFace, aE1, aE2);
440 if(aE1.IsNull() || aE2.IsNull()) {
441 closed = Standard_False;
444 // modified by NIZHNY-MKK Wed May 12 15:44:14 2004.END
449 //=======================================================================
452 //=======================================================================
453 void BOP_WireEdgeSet::IsUVISO(const TopoDS_Edge& E,
454 const TopoDS_Face& F,
455 Standard_Boolean& uiso,
456 Standard_Boolean& viso)
458 uiso = viso = Standard_False;
459 Standard_Real fE, lE,tolpc;
461 Handle(Geom2d_Curve) PC;
462 BOPTools_Tools2D::CurveOnSurface (E, F, PC, fE, lE, tolpc, Standard_False);//
465 Standard_ProgramError::Raise("BOP_WireEdgeSet::IsUVISO");
468 Handle(Standard_Type) TheType = PC->DynamicType();
469 if (TheType == STANDARD_TYPE(Geom2d_Line)) {
470 const Handle(Geom2d_Line)& HL = *((Handle(Geom2d_Line)*)&PC);
471 const gp_Dir2d& D = HL->Direction();
472 Standard_Real tol = Precision::Angular();
473 if (D.IsParallel(gp_Dir2d(0.,1.),tol)) {
474 uiso = Standard_True;
476 else if (D.IsParallel(gp_Dir2d(1.,0.),tol)) {
477 viso = Standard_True;
482 //=======================================================================
483 //function : IsUClosed
485 //=======================================================================
486 Standard_Boolean BOP_WireEdgeSet::IsUClosed(const TopoDS_Shape& E) const
488 const TopoDS_Edge& EE = TopoDS::Edge(E);
490 Standard_Boolean bid, closed;
491 IsUVISO(EE, myFace, closed, bid);
496 //=======================================================================
497 //function : IsVClosed
499 //=======================================================================
500 Standard_Boolean BOP_WireEdgeSet::IsVClosed(const TopoDS_Shape& E) const
502 const TopoDS_Edge& EE = TopoDS::Edge(E);
504 Standard_Boolean bid, closed;
505 IsUVISO (EE, myFace, bid, closed);
509 //=======================================================================
512 //=======================================================================
513 const TopoDS_Face& BOP_WireEdgeSet::Face() const
517 //=======================================================================
518 //function : BOP_Tools::KeptTwice
520 //=======================================================================
521 Standard_Boolean BOP_WireEdgeSet::KeptTwice (const TopoDS_Edge& aSpEF2) const
525 Standard_Integer iCnt=0;
527 const TopTools_ListOfShape& aWESList=StartElements();
529 TopTools_ListIteratorOfListOfShape anIt(aWESList);
530 for (; anIt.More(); anIt.Next()) {
531 const TopoDS_Shape& aSS=anIt.Value();
532 if (aSpEF2.IsSame(aSS)) {
535 return Standard_True;
539 return Standard_False;
541 //=======================================================================
542 //function : BOP_Tools::RemoveEdgeFromWES
544 //=======================================================================
545 void BOP_WireEdgeSet::RemoveEdgeFromWES(const TopoDS_Edge& aSpEF2)
548 TopTools_ListOfShape aTmpList;
549 aTmpList=StartElements();
553 TopTools_ListIteratorOfListOfShape anIt(aTmpList);
554 for (; anIt.More(); anIt.Next()) {
555 const TopoDS_Shape& aSS=anIt.Value();
556 if (!aSpEF2.IsEqual(aSS)) {
557 AddStartElement(aSS);
563 // modified by NIZHNY-MKK Fri May 30 10:18:38 2003.BEGIN
564 void GetOrientationVOnE(const TopoDS_Shape& V,
565 const TopoDS_Shape& E1,
566 const TopoDS_Shape& E2,
567 TopAbs_Orientation& o1,
568 TopAbs_Orientation& o2) {
569 TopTools_IndexedMapOfShape aMap;
571 TopExp::MapShapes(E1, TopAbs_VERTEX, aMap);
572 TopExp::MapShapes(E2, TopAbs_VERTEX, aMap);
574 if(aMap.Extent() > 1) {
575 TopExp_Explorer ex1, ex2;
576 ex1.Init(E1,TopAbs_VERTEX);
578 for(; ex1.More(); ex1.Next()) {
580 if (V.IsSame(ex1.Current())) {
581 ex2.Init(E2,TopAbs_VERTEX);
583 for(; ex2.More(); ex2.Next()) {
585 if (V.IsSame(ex2.Current())) {
586 o1 = ex1.Current().Orientation();
587 o2 = ex2.Current().Orientation();
600 if(E1.Orientation() == TopAbs_REVERSED)
602 o1 = VV.Orientation();
604 o2 = VV.Orientation();
608 // modified by NIZHNY-MKK Fri May 30 10:18:40 2003.END