1 // Created on: 1994-08-30
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <TopOpeBRepBuild_Builder.jxx>
18 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
19 #include <TopOpeBRepBuild_SolidBuilder.hxx>
21 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
22 #include <BRep_Tool.hxx>
23 #include <TopOpeBRepBuild_define.hxx>
24 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
26 #include <TopTools_ListOfShape.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRepCheck_Wire.hxx>
29 #include <BRepCheck.hxx>
30 #include <TopoDS_Iterator.hxx>
31 //#include <DBRep.hxx>
32 #include <BRepCheck_Analyzer.hxx>
33 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
34 #include <BRepCheck.hxx>
35 #include <BRepCheck_Result.hxx>
38 extern Standard_Boolean TopOpeBRepBuild_GettraceSPS();
41 //static Standard_Integer ifvNbFace = 0;
42 //static char *name = " ";
44 static void CorrectEdgeOrientation(TopoDS_Shape& aWire)
47 TopTools_ListOfShape anEdgeList, anAuxList, aTrueEdgeList;
49 TopoDS_Vertex vf, vl, v1f, v1l;
50 Standard_Boolean append = Standard_True;
52 TopoDS_Iterator tdi(aWire, Standard_False, Standard_False);
53 for(; tdi.More(); tdi.Next()) anEdgeList.Append(tdi.Value());
55 Standard_Integer n = anEdgeList.Extent();
58 TopTools_ListIteratorOfListOfShape anIt(anEdgeList);
60 TopoDS_Shape anCurEdge = anIt.Value();
61 TopExp::Vertices(TopoDS::Edge(anCurEdge), vf, vl, Standard_True);
62 aTrueEdgeList.Append(anCurEdge);
65 while(n > 0 && append) {
67 for(; anIt.More(); anIt.Next()) {
68 append = Standard_False;
69 anCurEdge = anIt.Value();
70 TopExp::Vertices(TopoDS::Edge(anCurEdge), v1f, v1l, Standard_True);
72 aTrueEdgeList.Append(anCurEdge);
74 append = Standard_True;
78 aTrueEdgeList.Append(anCurEdge);
80 append = Standard_True;
85 TopoDS_Shape anRevEdge = anCurEdge.Reversed();
86 aTrueEdgeList.Append(anRevEdge);
88 append = Standard_True;
92 TopoDS_Shape anRevEdge = anCurEdge.Reversed();
93 aTrueEdgeList.Append(anRevEdge);
95 append = Standard_True;
99 anAuxList.Append(anCurEdge);
102 anEdgeList.Assign(anAuxList);
103 anAuxList.Clear(); //something wrong in Assign when list contains 1 element.
104 n = anEdgeList.Extent();
105 anIt.Initialize(anEdgeList);
108 if(n > 0) aTrueEdgeList.Append(anEdgeList);
111 BB.MakeWire(TopoDS::Wire(aWire));
112 anIt.Initialize(aTrueEdgeList);
113 for(; anIt.More(); anIt.Next()) BB.Add(aWire, anIt.Value());
119 static void CorrectUnclosedWire(TopoDS_Shape& aWire)
121 // cout << "-------CorrectUnclosedWire" << endl;
123 TopoDS_Iterator tdi(aWire, Standard_False, Standard_False);
124 Standard_Integer nbe = 0;
125 for(; tdi.More(); tdi.Next()) {
127 const TopoDS_Shape& ed = tdi.Value();
128 Standard_Integer nbv = 0;
129 TopoDS_Iterator tdie(ed, Standard_False, Standard_False);
130 for(; tdie.More(); tdie.Next()) {
133 // cout << "Edge " << nbe << " : " << nbv << endl;
135 // cout << "Remove bad edge" << endl;
136 BB.Remove(aWire, ed);
140 TopTools_IndexedDataMapOfShapeListOfShape VElists;
142 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, VElists);
143 Standard_Integer nbVer = VElists.Extent(), i;
145 for(i = 1; i <= nbVer; i++) {
146 const TopTools_ListOfShape& Elist = VElists.FindFromIndex(i);
147 if(Elist.Extent() == 1) {
148 TopoDS_Shape anEdge = Elist.First();
149 // cout << "Remove redundant edge" << endl;
150 BB.Remove(aWire, anEdge);
155 //=======================================================================
156 //function : MergeShapes
158 //=======================================================================
161 void TopOpeBRepBuild_Builder::MergeShapes(const TopoDS_Shape& S1,const TopAbs_State ToBuild1,const TopoDS_Shape& S2,const TopAbs_State ToBuild2)
163 Standard_Boolean lesmemes = S1.IsEqual(S2);
166 cout<<"TopOpeBRepBuild : S1 == S2"<<endl;
179 Standard_Boolean S1null = S1.IsNull();
180 Standard_Boolean S2null = S2.IsNull();
185 //======================== debut KPart
191 //======================== fin KPart
193 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
194 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
196 // Create a face set <SFS> connected by edges
197 // -----------------------------------------
198 TopOpeBRepBuild_ShellFaceSet SFS;
201 SFS.DEBNumber(GdumpSHASETindex());
204 // NYI : SplitCompound appele par SplitShape
206 TopOpeBRepTool_ShapeExplorer ex1;
208 TopAbs_ShapeEnum t1=TopAbs_COMPOUND,tex1=TopAbs_COMPOUND;
211 t1 = tex1 = TopType(S1);
212 if ( t1 == TopAbs_COMPOUND ) {
213 tex1 = TopAbs_SOLID; ex1.Init(S1,tex1);
214 if ( ! ex1.More() ) {
215 tex1 = TopAbs_SHELL; ex1.Init(S1,tex1);
216 if ( ! ex1.More() ) {
217 tex1 = TopAbs_FACE; ex1.Init(S1,tex1);
219 tex1 = TopAbs_EDGE; ex1.Init(S1,tex1);
224 else if (t1 == TopAbs_WIRE) {
225 tex1 = TopAbs_EDGE; ex1.Init(S1,tex1);
227 else ex1.Init(S1,tex1);
228 SplitShapes(ex1,ToBuild1,ToBuild2,SFS,RevOri1);
231 TopOpeBRepTool_ShapeExplorer ex2;
233 TopAbs_ShapeEnum t2=TopAbs_COMPOUND,tex2=TopAbs_COMPOUND;
236 t2 = tex2 = TopType(S2);
237 if ( t2 == TopAbs_COMPOUND ) {
238 tex2 = TopAbs_SOLID; ex2.Init(S2,tex2);
239 if ( ! ex2.More() ) {
240 tex2 = TopAbs_SHELL; ex2.Init(S2,tex2);
241 if ( ! ex2.More() ) {
242 tex2 = TopAbs_FACE; ex2.Init(S2,tex2);
244 tex2 = TopAbs_EDGE; ex2.Init(S2,tex2);
249 else if (t2 == TopAbs_WIRE) {
250 tex2 = TopAbs_EDGE; ex2.Init(S2,tex2);
252 else ex2.Init(S2,tex2);
253 SplitShapes(ex2,ToBuild2,ToBuild1,SFS,RevOri2);
256 // S1 or S2 = COMPOUND : connect them the list of merged shapes build
257 // on the first subshape.
260 if ( t1 == TopAbs_COMPOUND ) {
261 TopTools_ListOfShape& L1 = ChangeMerged(S1,ToBuild1);
264 const TopoDS_Shape& SS1 = ex1.Current();
265 TopTools_ListOfShape& LSS1 = ChangeMerged(SS1,ToBuild1);
272 if ( t2 == TopAbs_COMPOUND ) {
273 TopTools_ListOfShape& L2 = ChangeMerged(S2,ToBuild2);
276 const TopoDS_Shape& SS2 = ex2.Current();
277 TopTools_ListOfShape& LSS2 = ChangeMerged(SS2,ToBuild2);
288 //=======================================================================
289 //function : Classify
290 //purpose : LocOpe use
291 //=======================================================================
293 Standard_Boolean TopOpeBRepBuild_Builder::Classify() const
295 return myClassifyVal;
298 //=======================================================================
299 //function : ChangeClassify
300 //purpose : LocOpe use
301 //=======================================================================
303 void TopOpeBRepBuild_Builder::ChangeClassify(const Standard_Boolean classify)
305 myClassifyDef = Standard_True;
306 myClassifyVal = classify;
309 //=======================================================================
310 //function : MergeSolids
312 //=======================================================================
314 void TopOpeBRepBuild_Builder::MergeSolids(const TopoDS_Shape& S1,const TopAbs_State ToBuild1,const TopoDS_Shape& S2,const TopAbs_State ToBuild2)
316 MergeShapes(S1,ToBuild1,S2,ToBuild2);
320 //=======================================================================
321 //function : MergeSolid
323 //=======================================================================
325 void TopOpeBRepBuild_Builder::MergeSolid(const TopoDS_Shape& S,const TopAbs_State ToBuild)
328 MergeShapes(S,ToBuild,Snull,ToBuild);
332 //=======================================================================
333 //function : MakeSolids
335 //=======================================================================
337 void TopOpeBRepBuild_Builder::MakeSolids(TopOpeBRepBuild_SolidBuilder& SOBU,TopTools_ListOfShape& L)
339 TopoDS_Shape newSolid;
340 TopoDS_Shape newShell;
341 for (SOBU.InitSolid(); SOBU.MoreSolid(); SOBU.NextSolid()) {
342 myBuildTool.MakeSolid(newSolid);
343 for (SOBU.InitShell(); SOBU.MoreShell(); SOBU.NextShell()) {
344 Standard_Boolean isold = SOBU.IsOldShell();
345 if (isold) newShell = SOBU.OldShell();
347 myBuildTool.MakeShell(newShell);
348 for (SOBU.InitFace(); SOBU.MoreFace(); SOBU.NextFace()) {
349 TopoDS_Shape F = SOBU.Face();
350 myBuildTool.AddShellFace(newShell,F);
353 myBuildTool.Closed(newShell,Standard_True); // NYI : check exact du caractere closed du shell
354 myBuildTool.AddSolidShell(newSolid,newShell);
359 //=======================================================================
360 //function : MakeShells
362 //=======================================================================
364 void TopOpeBRepBuild_Builder::MakeShells(TopOpeBRepBuild_SolidBuilder& SOBU,TopTools_ListOfShape& L)
366 TopoDS_Shape newShell;
367 for (SOBU.InitShell(); SOBU.MoreShell(); SOBU.NextShell()) {
368 Standard_Boolean isold = SOBU.IsOldShell();
369 if (isold) newShell = SOBU.OldShell();
371 myBuildTool.MakeShell(newShell);
372 for (SOBU.InitFace(); SOBU.MoreFace(); SOBU.NextFace()) {
373 TopoDS_Shape F = SOBU.Face();
374 myBuildTool.AddShellFace(newShell,F);
383 //=======================================================================
384 //function : MakeFaces
386 //=======================================================================
388 void TopOpeBRepBuild_Builder::MakeFaces(const TopoDS_Shape& aFace,TopOpeBRepBuild_FaceBuilder& FABU,TopTools_ListOfShape& L)
391 Standard_Integer iF = 0; Standard_Boolean tSPS = GtraceSPS(aFace,iF);
392 if(tSPS){GdumpFABU(FABU);}
394 Standard_Boolean hashds = (!myDataStructure.IsNull());
395 TopoDS_Shape newFace;
396 TopoDS_Shape newWire;
398 for (FABU.InitFace(); FABU.MoreFace(); FABU.NextFace()) {
399 myBuildTool.CopyFace(aFace,newFace);
400 Standard_Boolean hns = Standard_False;
402 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
403 hns = BDS.HasNewSurface(aFace);
405 const Handle(Geom_Surface)& SU = BDS.NewSurface(aFace);
406 myBuildTool.UpdateSurface(newFace,SU);
411 for (FABU.InitWire(); FABU.MoreWire(); FABU.NextWire()) {
412 Standard_Boolean isold = FABU.IsOldWire();
413 if (isold) newWire = FABU.OldWire();
415 myBuildTool.MakeWire(newWire);
416 for(FABU.InitEdge(); FABU.MoreEdge(); FABU.NextEdge()) {
417 TopoDS_Shape E = FABU.Edge();
418 if (hns) myBuildTool.UpdateSurface(E,aFace,newFace);
419 myBuildTool.AddWireEdge(newWire,E);
424 BRepCheck_Analyzer bca(newWire, Standard_False);
425 if (!bca.IsValid()) {
426 newWire.Free(Standard_True);
427 CorrectUnclosedWire(newWire);
428 const Handle(BRepCheck_Result)& bcr = bca.Result(newWire);
429 BRepCheck_ListIteratorOfListOfStatus itl(bcr->Status());
430 for(; itl.More(); itl.Next() ) {
431 if(itl.Value() == BRepCheck_BadOrientationOfSubshape) {
432 CorrectEdgeOrientation(newWire);
438 myBuildTool.Closed(newWire,Standard_True); // NYI : check exact du caractere closed du wire
439 myBuildTool.AddFaceWire(newFace,newWire);
448 //=======================================================================
449 //function : MakeEdges
451 //=======================================================================
453 void TopOpeBRepBuild_Builder::MakeEdges(const TopoDS_Shape& anEdge,TopOpeBRepBuild_EdgeBuilder& EDBU,TopTools_ListOfShape& L)
456 Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(anEdge,iE);
457 Standard_Integer ne = 0;
460 Standard_Integer nvertex = 0;
461 for (TopOpeBRepTool_ShapeExplorer ex(anEdge,TopAbs_VERTEX); ex.More(); ex.Next()) nvertex++;
463 TopoDS_Shape newEdge;
464 for (EDBU.InitEdge(); EDBU.MoreEdge(); EDBU.NextEdge()) {
466 // 1 vertex sur edge courante => suppression edge
467 Standard_Integer nloop = 0;
468 for (EDBU.InitVertex(); EDBU.MoreVertex(); EDBU.NextVertex()) nloop++;
469 if ( nloop <= 1 ) continue;
471 myBuildTool.CopyEdge(anEdge,newEdge);
473 Standard_Boolean hasvertex = Standard_False;
474 for (EDBU.InitVertex(); EDBU.MoreVertex(); EDBU.NextVertex()) {
475 TopoDS_Shape V = EDBU.Vertex();
476 TopAbs_Orientation Vori = V.Orientation();
478 Standard_Boolean hassd = myDataStructure->HasSameDomain(V);
480 // on prend le vertex reference de V
481 Standard_Integer iref = myDataStructure->SameDomainReference(V);
482 V = myDataStructure->Shape(iref);
486 TopAbs_Orientation oriV = V.Orientation();
487 if ( oriV != TopAbs_EXTERNAL ) {
489 Standard_Boolean equafound = Standard_False;
490 TopExp_Explorer exE(newEdge,TopAbs_VERTEX);
491 for (; exE.More(); exE.Next() ) {
492 const TopoDS_Shape& VE = exE.Current();
493 TopAbs_Orientation oriVE = VE.Orientation();
494 if ( V.IsEqual(VE) ) {
495 equafound = Standard_True;
498 else if (oriVE == TopAbs_FORWARD || oriVE == TopAbs_REVERSED) {
500 equafound = Standard_True;
504 else if (oriVE == TopAbs_INTERNAL || oriVE == TopAbs_EXTERNAL) {
505 Standard_Real parV = EDBU.Parameter();
506 Standard_Real parVE = BRep_Tool::Parameter(TopoDS::Vertex(VE),
507 TopoDS::Edge(newEdge));
508 if ( parV == parVE ) {
509 equafound = Standard_True;
515 hasvertex = Standard_True;
516 Standard_Real parV = EDBU.Parameter();
517 myBuildTool.AddEdgeVertex(newEdge,V);
518 myBuildTool.Parameter(newEdge,V,parV);
522 } // loop on vertices of new edge newEdge
525 if(tSPS){cout<<endl;}
526 if(tSPS){cout<<"V of new edge "<<++ne<<endl;}
527 if(tSPS){GdumpEDG(newEdge);}
530 if (hasvertex) L.Append(newEdge);
531 } // loop on EDBU edges
535 //=======================================================================
536 //function : IsMerged
538 //=======================================================================
540 Standard_Boolean TopOpeBRepBuild_Builder::IsMerged(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
542 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
543 if ( ToBuild == TopAbs_OUT ) p = &myMergedOUT;
544 else if ( ToBuild == TopAbs_IN ) p = &myMergedIN;
545 else if ( ToBuild == TopAbs_ON ) p = &myMergedON;
546 if ( p == NULL ) return Standard_False;
548 Standard_Boolean notbound = ! (*p).IsBound(S);
550 return Standard_False;
553 const TopTools_ListOfShape& L = Merged(S,ToBuild);
554 Standard_Boolean isempty = L.IsEmpty();
560 //=======================================================================
563 //=======================================================================
565 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::Merged(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
567 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
568 if ( ToBuild == TopAbs_OUT ) p = &myMergedOUT;
569 else if ( ToBuild == TopAbs_IN ) p = &myMergedIN;
570 else if ( ToBuild == TopAbs_ON ) p = &myMergedON;
571 if ( p == NULL ) return myEmptyShapeList;
573 if ( ! (*p).IsBound(S) ) {
574 return myEmptyShapeList;
577 const TopTools_ListOfShape& L = (*p)(S).ListOnState();
583 //=======================================================================
584 //function : ChangeMerged
586 //=======================================================================
588 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeMerged(const TopoDS_Shape& S, const TopAbs_State ToBuild)
590 TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
591 if ( ToBuild == TopAbs_OUT ) p = &myMergedOUT;
592 else if ( ToBuild == TopAbs_IN ) p = &myMergedIN;
593 else if ( ToBuild == TopAbs_ON ) p = &myMergedON;
594 if ( p == NULL ) return myEmptyShapeList;
596 if ( ! (*p).IsBound(S) ) {
597 TopOpeBRepDS_ListOfShapeOn1State thelist;
598 (*p).Bind(S, thelist);
600 TopTools_ListOfShape& L = (*p)(S).ChangeListOnState();
604 //=======================================================================
605 //function : MergeEdges
607 //=======================================================================
609 void TopOpeBRepBuild_Builder::MergeEdges(const TopTools_ListOfShape& ,//L1,
610 const TopAbs_State ,//ToBuild1,
611 const TopTools_ListOfShape& ,//L2,
612 const TopAbs_State ,//ToBuild2,
613 const Standard_Boolean ,//Keepon1,
614 const Standard_Boolean ,//Keepon2,
615 const Standard_Boolean )//Keepon12)
619 //=======================================================================
620 //function : MergeFaces
622 //=======================================================================
624 void TopOpeBRepBuild_Builder::MergeFaces(const TopTools_ListOfShape& , //S1,
625 const TopAbs_State , //ToBuild1,
626 const TopTools_ListOfShape& , //S2,
627 const TopAbs_State , //ToBuild2
628 const Standard_Boolean ,//onA,
629 const Standard_Boolean ,//onB,
630 const Standard_Boolean )//onAB)