1 // Created on: 1994-08-30
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1994-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.
22 #include <TopOpeBRepBuild_Builder.jxx>
23 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
24 #include <TopOpeBRepBuild_SolidBuilder.hxx>
26 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
27 #include <BRep_Tool.hxx>
28 #include <TopOpeBRepBuild_define.hxx>
29 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
31 #include <TopTools_ListOfShape.hxx>
32 #include <BRep_Builder.hxx>
33 #include <BRepCheck_Wire.hxx>
34 #include <BRepCheck.hxx>
35 #include <TopoDS_Iterator.hxx>
36 //#include <DBRep.hxx>
37 #include <BRepCheck_Analyzer.hxx>
38 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
39 #include <BRepCheck.hxx>
40 #include <BRepCheck_Result.hxx>
43 Standard_IMPORT Standard_Boolean TopOpeBRepBuild_GettraceSPS();
46 //static Standard_Integer ifvNbFace = 0;
47 //static char *name = " ";
49 static void CorrectEdgeOrientation(TopoDS_Shape& aWire)
52 TopTools_ListOfShape anEdgeList, anAuxList, aTrueEdgeList;
54 TopoDS_Vertex vf, vl, v1f, v1l;
55 Standard_Boolean append = Standard_True;
57 TopoDS_Iterator tdi(aWire, Standard_False, Standard_False);
58 for(; tdi.More(); tdi.Next()) anEdgeList.Append(tdi.Value());
60 Standard_Integer n = anEdgeList.Extent();
63 TopTools_ListIteratorOfListOfShape anIt(anEdgeList);
65 TopoDS_Shape anCurEdge = anIt.Value();
66 TopExp::Vertices(TopoDS::Edge(anCurEdge), vf, vl, Standard_True);
67 aTrueEdgeList.Append(anCurEdge);
70 while(n > 0 && append) {
72 for(; anIt.More(); anIt.Next()) {
73 append = Standard_False;
74 anCurEdge = anIt.Value();
75 TopExp::Vertices(TopoDS::Edge(anCurEdge), v1f, v1l, Standard_True);
77 aTrueEdgeList.Append(anCurEdge);
79 append = Standard_True;
83 aTrueEdgeList.Append(anCurEdge);
85 append = Standard_True;
90 TopoDS_Shape anRevEdge = anCurEdge.Reversed();
91 aTrueEdgeList.Append(anRevEdge);
93 append = Standard_True;
97 TopoDS_Shape anRevEdge = anCurEdge.Reversed();
98 aTrueEdgeList.Append(anRevEdge);
100 append = Standard_True;
104 anAuxList.Append(anCurEdge);
107 anEdgeList.Assign(anAuxList);
108 anAuxList.Clear(); //something wrong in Assign when list contains 1 element.
109 n = anEdgeList.Extent();
110 anIt.Initialize(anEdgeList);
113 if(n > 0) aTrueEdgeList.Append(anEdgeList);
116 BB.MakeWire(TopoDS::Wire(aWire));
117 anIt.Initialize(aTrueEdgeList);
118 for(; anIt.More(); anIt.Next()) BB.Add(aWire, anIt.Value());
124 static void CorrectUnclosedWire(TopoDS_Shape& aWire)
126 // cout << "-------CorrectUnclosedWire" << endl;
128 TopoDS_Iterator tdi(aWire, Standard_False, Standard_False);
129 Standard_Integer nbe = 0;
130 for(; tdi.More(); tdi.Next()) {
132 const TopoDS_Shape& ed = tdi.Value();
133 Standard_Integer nbv = 0;
134 TopoDS_Iterator tdie(ed, Standard_False, Standard_False);
135 for(; tdie.More(); tdie.Next()) {
138 // cout << "Edge " << nbe << " : " << nbv << endl;
140 // cout << "Remove bad edge" << endl;
141 BB.Remove(aWire, ed);
145 TopTools_IndexedDataMapOfShapeListOfShape VElists;
147 TopExp::MapShapesAndAncestors(aWire, TopAbs_VERTEX, TopAbs_EDGE, VElists);
148 Standard_Integer nbVer = VElists.Extent(), i;
150 for(i = 1; i <= nbVer; i++) {
151 const TopTools_ListOfShape& Elist = VElists.FindFromIndex(i);
152 if(Elist.Extent() == 1) {
153 TopoDS_Shape anEdge = Elist.First();
154 // cout << "Remove redundant edge" << endl;
155 BB.Remove(aWire, anEdge);
160 //=======================================================================
161 //function : MergeShapes
163 //=======================================================================
166 void TopOpeBRepBuild_Builder::MergeShapes(const TopoDS_Shape& S1,const TopAbs_State ToBuild1,const TopoDS_Shape& S2,const TopAbs_State ToBuild2)
168 Standard_Boolean lesmemes = S1.IsEqual(S2);
171 cout<<"TopOpeBRepBuild : S1 == S2"<<endl;
184 Standard_Boolean S1null = S1.IsNull();
185 Standard_Boolean S2null = S2.IsNull();
190 //======================== debut KPart
196 //======================== fin KPart
198 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
199 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
201 // Create a face set <SFS> connected by edges
202 // -----------------------------------------
203 TopOpeBRepBuild_ShellFaceSet SFS;
206 SFS.DEBNumber(GdumpSHASETindex());
209 // NYI : SplitCompound appele par SplitShape
211 TopOpeBRepTool_ShapeExplorer ex1;
213 TopAbs_ShapeEnum t1,tex1;
215 TopAbs_ShapeEnum t1=TopAbs_COMPOUND,tex1=TopAbs_COMPOUND;
218 t1 = tex1 = TopType(S1);
219 if ( t1 == TopAbs_COMPOUND ) {
220 tex1 = TopAbs_SOLID; ex1.Init(S1,tex1);
221 if ( ! ex1.More() ) {
222 tex1 = TopAbs_SHELL; ex1.Init(S1,tex1);
223 if ( ! ex1.More() ) {
224 tex1 = TopAbs_FACE; ex1.Init(S1,tex1);
226 tex1 = TopAbs_EDGE; ex1.Init(S1,tex1);
231 else if (t1 == TopAbs_WIRE) {
232 tex1 = TopAbs_EDGE; ex1.Init(S1,tex1);
234 else ex1.Init(S1,tex1);
235 SplitShapes(ex1,ToBuild1,ToBuild2,SFS,RevOri1);
238 TopOpeBRepTool_ShapeExplorer ex2;
240 TopAbs_ShapeEnum t2,tex2;
242 TopAbs_ShapeEnum t2=TopAbs_COMPOUND,tex2=TopAbs_COMPOUND;
245 t2 = tex2 = TopType(S2);
246 if ( t2 == TopAbs_COMPOUND ) {
247 tex2 = TopAbs_SOLID; ex2.Init(S2,tex2);
248 if ( ! ex2.More() ) {
249 tex2 = TopAbs_SHELL; ex2.Init(S2,tex2);
250 if ( ! ex2.More() ) {
251 tex2 = TopAbs_FACE; ex2.Init(S2,tex2);
253 tex2 = TopAbs_EDGE; ex2.Init(S2,tex2);
258 else if (t2 == TopAbs_WIRE) {
259 tex2 = TopAbs_EDGE; ex2.Init(S2,tex2);
261 else ex2.Init(S2,tex2);
262 SplitShapes(ex2,ToBuild2,ToBuild1,SFS,RevOri2);
265 // S1 or S2 = COMPOUND : connect them the list of merged shapes build
266 // on the first subshape.
269 if ( t1 == TopAbs_COMPOUND ) {
270 TopTools_ListOfShape& L1 = ChangeMerged(S1,ToBuild1);
273 const TopoDS_Shape& SS1 = ex1.Current();
274 TopTools_ListOfShape& LSS1 = ChangeMerged(SS1,ToBuild1);
281 if ( t2 == TopAbs_COMPOUND ) {
282 TopTools_ListOfShape& L2 = ChangeMerged(S2,ToBuild2);
285 const TopoDS_Shape& SS2 = ex2.Current();
286 TopTools_ListOfShape& LSS2 = ChangeMerged(SS2,ToBuild2);
297 //=======================================================================
298 //function : Classify
299 //purpose : LocOpe use
300 //=======================================================================
302 Standard_Boolean TopOpeBRepBuild_Builder::Classify() const
304 return myClassifyVal;
307 //=======================================================================
308 //function : ChangeClassify
309 //purpose : LocOpe use
310 //=======================================================================
312 void TopOpeBRepBuild_Builder::ChangeClassify(const Standard_Boolean classify)
314 myClassifyDef = Standard_True;
315 myClassifyVal = classify;
318 //=======================================================================
319 //function : MergeSolids
321 //=======================================================================
323 void TopOpeBRepBuild_Builder::MergeSolids(const TopoDS_Shape& S1,const TopAbs_State ToBuild1,const TopoDS_Shape& S2,const TopAbs_State ToBuild2)
325 MergeShapes(S1,ToBuild1,S2,ToBuild2);
329 //=======================================================================
330 //function : MergeSolid
332 //=======================================================================
334 void TopOpeBRepBuild_Builder::MergeSolid(const TopoDS_Shape& S,const TopAbs_State ToBuild)
337 MergeShapes(S,ToBuild,Snull,ToBuild);
341 //=======================================================================
342 //function : MakeSolids
344 //=======================================================================
346 void TopOpeBRepBuild_Builder::MakeSolids(TopOpeBRepBuild_SolidBuilder& SOBU,TopTools_ListOfShape& L)
348 TopoDS_Shape newSolid;
349 TopoDS_Shape newShell;
350 for (SOBU.InitSolid(); SOBU.MoreSolid(); SOBU.NextSolid()) {
351 myBuildTool.MakeSolid(newSolid);
352 for (SOBU.InitShell(); SOBU.MoreShell(); SOBU.NextShell()) {
353 Standard_Boolean isold = SOBU.IsOldShell();
354 if (isold) newShell = SOBU.OldShell();
356 myBuildTool.MakeShell(newShell);
357 for (SOBU.InitFace(); SOBU.MoreFace(); SOBU.NextFace()) {
358 TopoDS_Shape F = SOBU.Face();
359 myBuildTool.AddShellFace(newShell,F);
362 myBuildTool.Closed(newShell,Standard_True); // NYI : check exact du caractere closed du shell
363 myBuildTool.AddSolidShell(newSolid,newShell);
368 //=======================================================================
369 //function : MakeShells
371 //=======================================================================
373 void TopOpeBRepBuild_Builder::MakeShells(TopOpeBRepBuild_SolidBuilder& SOBU,TopTools_ListOfShape& L)
375 TopoDS_Shape newShell;
376 for (SOBU.InitShell(); SOBU.MoreShell(); SOBU.NextShell()) {
377 Standard_Boolean isold = SOBU.IsOldShell();
378 if (isold) newShell = SOBU.OldShell();
380 myBuildTool.MakeShell(newShell);
381 for (SOBU.InitFace(); SOBU.MoreFace(); SOBU.NextFace()) {
382 TopoDS_Shape F = SOBU.Face();
383 myBuildTool.AddShellFace(newShell,F);
392 //=======================================================================
393 //function : MakeFaces
395 //=======================================================================
397 void TopOpeBRepBuild_Builder::MakeFaces(const TopoDS_Shape& aFace,TopOpeBRepBuild_FaceBuilder& FABU,TopTools_ListOfShape& L)
400 Standard_Integer iF = 0; Standard_Boolean tSPS = GtraceSPS(aFace,iF);
401 if(tSPS){GdumpFABU(FABU);}
403 Standard_Boolean hashds = (!myDataStructure.IsNull());
404 TopoDS_Shape newFace;
405 TopoDS_Shape newWire;
407 for (FABU.InitFace(); FABU.MoreFace(); FABU.NextFace()) {
408 myBuildTool.CopyFace(aFace,newFace);
409 Standard_Boolean hns = Standard_False;
411 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
412 hns = BDS.HasNewSurface(aFace);
414 const Handle(Geom_Surface)& SU = BDS.NewSurface(aFace);
415 myBuildTool.UpdateSurface(newFace,SU);
420 for (FABU.InitWire(); FABU.MoreWire(); FABU.NextWire()) {
421 Standard_Boolean isold = FABU.IsOldWire();
422 if (isold) newWire = FABU.OldWire();
424 myBuildTool.MakeWire(newWire);
425 for(FABU.InitEdge(); FABU.MoreEdge(); FABU.NextEdge()) {
426 TopoDS_Shape E = FABU.Edge();
427 if (hns) myBuildTool.UpdateSurface(E,aFace,newFace);
428 myBuildTool.AddWireEdge(newWire,E);
433 BRepCheck_Analyzer bca(newWire, Standard_False);
434 if (!bca.IsValid()) {
435 newWire.Free(Standard_True);
436 CorrectUnclosedWire(newWire);
437 const Handle(BRepCheck_Result)& bcr = bca.Result(newWire);
438 BRepCheck_ListIteratorOfListOfStatus itl(bcr->Status());
439 for(; itl.More(); itl.Next() ) {
440 if(itl.Value() == BRepCheck_BadOrientationOfSubshape) {
441 CorrectEdgeOrientation(newWire);
447 myBuildTool.Closed(newWire,Standard_True); // NYI : check exact du caractere closed du wire
448 myBuildTool.AddFaceWire(newFace,newWire);
457 //=======================================================================
458 //function : MakeEdges
460 //=======================================================================
462 void TopOpeBRepBuild_Builder::MakeEdges(const TopoDS_Shape& anEdge,TopOpeBRepBuild_EdgeBuilder& EDBU,TopTools_ListOfShape& L)
465 Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(anEdge,iE);
466 Standard_Integer ne = 0;
469 Standard_Integer nvertex = 0;
470 for (TopOpeBRepTool_ShapeExplorer ex(anEdge,TopAbs_VERTEX); ex.More(); ex.Next()) nvertex++;
472 TopoDS_Shape newEdge;
473 for (EDBU.InitEdge(); EDBU.MoreEdge(); EDBU.NextEdge()) {
475 // 1 vertex sur edge courante => suppression edge
476 Standard_Integer nloop = 0;
477 for (EDBU.InitVertex(); EDBU.MoreVertex(); EDBU.NextVertex()) nloop++;
478 if ( nloop <= 1 ) continue;
480 myBuildTool.CopyEdge(anEdge,newEdge);
482 Standard_Boolean hasvertex = Standard_False;
483 for (EDBU.InitVertex(); EDBU.MoreVertex(); EDBU.NextVertex()) {
484 TopoDS_Shape V = EDBU.Vertex();
485 TopAbs_Orientation Vori = V.Orientation();
487 Standard_Boolean hassd = myDataStructure->HasSameDomain(V);
489 // on prend le vertex reference de V
490 Standard_Integer iref = myDataStructure->SameDomainReference(V);
491 V = myDataStructure->Shape(iref);
495 TopAbs_Orientation oriV = V.Orientation();
496 if ( oriV != TopAbs_EXTERNAL ) {
498 Standard_Boolean equafound = Standard_False;
499 TopExp_Explorer exE(newEdge,TopAbs_VERTEX);
500 for (; exE.More(); exE.Next() ) {
501 const TopoDS_Shape& VE = exE.Current();
502 TopAbs_Orientation oriVE = VE.Orientation();
503 if ( V.IsEqual(VE) ) {
504 equafound = Standard_True;
507 else if (oriVE == TopAbs_FORWARD || oriVE == TopAbs_REVERSED) {
509 equafound = Standard_True;
513 else if (oriVE == TopAbs_INTERNAL || oriVE == TopAbs_EXTERNAL) {
514 Standard_Real parV = EDBU.Parameter();
515 Standard_Real parVE = BRep_Tool::Parameter(TopoDS::Vertex(VE),
516 TopoDS::Edge(newEdge));
517 if ( parV == parVE ) {
518 equafound = Standard_True;
524 hasvertex = Standard_True;
525 Standard_Real parV = EDBU.Parameter();
526 myBuildTool.AddEdgeVertex(newEdge,V);
527 myBuildTool.Parameter(newEdge,V,parV);
531 } // loop on vertices of new edge newEdge
534 if(tSPS){cout<<endl;}
535 if(tSPS){cout<<"V of new edge "<<++ne<<endl;}
536 if(tSPS){GdumpEDG(newEdge);}
539 if (hasvertex) L.Append(newEdge);
540 } // loop on EDBU edges
544 //=======================================================================
545 //function : IsMerged
547 //=======================================================================
549 Standard_Boolean TopOpeBRepBuild_Builder::IsMerged(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
551 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
552 if ( ToBuild == TopAbs_OUT ) p = &myMergedOUT;
553 else if ( ToBuild == TopAbs_IN ) p = &myMergedIN;
554 else if ( ToBuild == TopAbs_ON ) p = &myMergedON;
555 if ( p == NULL ) return Standard_False;
557 Standard_Boolean notbound = ! (*p).IsBound(S);
559 return Standard_False;
562 const TopTools_ListOfShape& L = Merged(S,ToBuild);
563 Standard_Boolean isempty = L.IsEmpty();
569 //=======================================================================
572 //=======================================================================
574 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::Merged(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
576 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
577 if ( ToBuild == TopAbs_OUT ) p = &myMergedOUT;
578 else if ( ToBuild == TopAbs_IN ) p = &myMergedIN;
579 else if ( ToBuild == TopAbs_ON ) p = &myMergedON;
580 if ( p == NULL ) return myEmptyShapeList;
582 if ( ! (*p).IsBound(S) ) {
583 return myEmptyShapeList;
586 const TopTools_ListOfShape& L = (*p)(S).ListOnState();
592 //=======================================================================
593 //function : ChangeMerged
595 //=======================================================================
597 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeMerged(const TopoDS_Shape& S, const TopAbs_State ToBuild)
599 TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
600 if ( ToBuild == TopAbs_OUT ) p = &myMergedOUT;
601 else if ( ToBuild == TopAbs_IN ) p = &myMergedIN;
602 else if ( ToBuild == TopAbs_ON ) p = &myMergedON;
603 if ( p == NULL ) return myEmptyShapeList;
605 if ( ! (*p).IsBound(S) ) {
606 TopOpeBRepDS_ListOfShapeOn1State thelist;
607 (*p).Bind(S, thelist);
609 TopTools_ListOfShape& L = (*p)(S).ChangeListOnState();
613 //=======================================================================
614 //function : MergeEdges
616 //=======================================================================
618 void TopOpeBRepBuild_Builder::MergeEdges(const TopTools_ListOfShape& ,//L1,
619 const TopAbs_State ,//ToBuild1,
620 const TopTools_ListOfShape& ,//L2,
621 const TopAbs_State ,//ToBuild2,
622 const Standard_Boolean ,//Keepon1,
623 const Standard_Boolean ,//Keepon2,
624 const Standard_Boolean )//Keepon12)
628 //=======================================================================
629 //function : MergeFaces
631 //=======================================================================
633 void TopOpeBRepBuild_Builder::MergeFaces(const TopTools_ListOfShape& , //S1,
634 const TopAbs_State , //ToBuild1,
635 const TopTools_ListOfShape& , //S2,
636 const TopAbs_State , //ToBuild2
637 const Standard_Boolean ,//onA,
638 const Standard_Boolean ,//onB,
639 const Standard_Boolean )//onAB)