// Created on: 1996-03-07 // Created by: Jean Yves LEBEY // Copyright (c) 1996-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef OCCT_DEBUG extern Standard_Boolean TopOpeBRepBuild_GetcontextNOPURGE(); extern Standard_Boolean TopOpeBRepBuild_GetcontextNOCORRISO(); extern Standard_Boolean TopOpeBRepBuild_GettraceCHK(); #define DEBSHASET(sarg,meth,shaset,str) \ TCollection_AsciiString sarg((meth));(sarg)=(sarg)+(shaset).DEBNumber()+(str); Standard_EXPORT void debgfabu(const Standard_Integer i) {cout<<"++ debgfabu "< #include #endif Standard_EXPORT Standard_Boolean FUN_tool_ClosedW(const TopoDS_Wire& W); // Unused : /*#ifdef OCCT_DEBUG static void FUN_Raise(){cout<<"--------- ERROR in GWESMakeFaces ---------"<ChangeDS(); TopTools_IndexedMapOfShape mapPIE; // pseudo internal edges FABU.DetectPseudoInternalEdge(mapPIE); TopTools_IndexedDataMapOfShapeShape mapVVsameG,mapVon1Edge,mapVVref; FABU.DetectUnclosedWire(mapVVsameG,mapVon1Edge); Standard_Integer nVV = mapVVsameG.Extent(); if (nVV > 0) { // Updating the DS with same domain vertices, // filling up map for (Standard_Integer i = 1; i <= nVV; i++) { const TopoDS_Shape& V = mapVVsameG.FindKey(i); Standard_Boolean hsdm = myDataStructure->HasSameDomain(V); if (!hsdm) { Standard_Integer rankV = BDS.AncestorRank(V); const TopoDS_Shape& VsameG = mapVVsameG.FindFromIndex(i); // MSV Oct 4, 2001: prefer old vertex as SameDomainReference Standard_Integer rankVsameG = BDS.AncestorRank(VsameG); Standard_Boolean otherRef = (rankVsameG != 0 && rankV != 1); if (otherRef) BDS.FillShapesSameDomain(VsameG,V); else BDS.FillShapesSameDomain(V,VsameG); hsdm = myDataStructure->HasSameDomain(V); } if (hsdm) { Standard_Integer Iref = myDataStructure->SameDomainReference(V); const TopoDS_Shape& Vref = myDataStructure->Shape(Iref); mapVVref.Add(V,Vref); } } FABU.CorrectGclosedWire(mapVVref,mapVon1Edge); FABU.DetectUnclosedWire(mapVVsameG,mapVon1Edge); } } TopTools_DataMapOfShapeInteger MWisOld; TopTools_IndexedMapOfOrientedShape MshNOK; GFABUMakeFaces(FF,FABU,LOF,MWisOld); // 2. on periodic face F : // finds up faulty shapes MshNOK to avoid when building up shapes // (edge no longer closing that appears twice in the new face) if (topurge) { #ifdef DRAW if (tSPS) { cout<DynamicType(); // Standard_Boolean istrim = ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) ); // if ( istrim && tt1 == GeomAbs_Plane) Surf = Handle(Geom_RectangularTrimmedSurface)::DownCast(Surf)->BasisSurface(); Standard_Real tolFF = BRep_Tool::Tolerance(TopoDS::Face(FF)); BRep_Builder BB; //--ofv: // Unfortunately, the function GFillONPartsWES2() from file TopOpeBRepBuild_BuilderON.cxx sets orientation of // some section edges as INTERNAL or EXTERNAL, but they should be FORWARD or REVERSED. It probably makes faces // without closed boundary, for example. So, we must check carefuly edges with orientation INTERNAL(EXTERNAL). // Bugs: 60936, 60937, 60938 (cut, fuse, common shapes) TopoDS_Compound CmpOfEdges; BRep_Builder BldCmpOfEdges; TopTools_IndexedDataMapOfShapeListOfShape mapVOE; TopoDS_Face tdF = TopoDS::Face(FF); //--ofv. FABU.InitFace(); for (; FABU.MoreFace(); FABU.NextFace()) { Standard_Integer nbnewWwithe = 0; Standard_Integer nboldW = 0; BB.MakeFace(newFace,Surf,Loc,tolFF); // myBuildTool.CopyFace(FF,newFace); Standard_Integer nbw = FABU.InitWire(); for (; FABU.MoreWire(); FABU.NextWire()) { Standard_Integer ne = 0; Standard_Integer neFORWARD = 0; Standard_Integer neREVERSED = 0; Standard_Integer neINTERNAL = 0; Standard_Integer neEXTERNAL = 0; Standard_Boolean isold = FABU.IsOldWire(); if(isold) { nboldW++; newWire = TopoDS::Wire(FABU.OldWire()); } else { BldCmpOfEdges.MakeCompound(CmpOfEdges);//new compound myBuildTool.MakeWire(newWire); FABU.InitEdge(); for(; FABU.MoreEdge(); FABU.NextEdge()) { TopoDS_Edge newEdge = TopoDS::Edge(FABU.Edge()); // if (mEtouched.Contains(newEdge)) continue;// xpu290498 // mEtouched.Add(newEdge);// xpu290498 //--ofv: Standard_Integer nadde = FABU.AddEdgeWire(newEdge,CmpOfEdges); ne += nadde; //Standard_Integer nadde = FABU.AddEdgeWire(newEdge,newWire); //ne += nadde; //--ofv. TopAbs_Orientation oE = newEdge.Orientation(); if (oE == TopAbs_INTERNAL) neINTERNAL++; else if (oE == TopAbs_EXTERNAL) neEXTERNAL++; else if (oE == TopAbs_FORWARD) neFORWARD++; else if (oE == TopAbs_REVERSED) neREVERSED++; Standard_Boolean hasPC = FC2D_HasCurveOnSurface(newEdge,newFace); // jyl980402+ if (!hasPC) // jyl980402+ { // jyl980402+ Standard_Real tolE = BRep_Tool::Tolerance(newEdge); // jyl980402+ Standard_Real f2,l2,tolpc; Handle(Geom2d_Curve) C2D; // jyl980402+ //C2D = FC2D_CurveOnSurface(newEdge,newFace,f2,l2,tolpc); // jyl980402+ C2D = FC2D_CurveOnSurface(newEdge,newFace,f2,l2,tolpc, Standard_True); // xpu051198 (CTS21701) if(C2D.IsNull()) throw Standard_ProgramError("TopOpeBRepBuild_Builder::GFABUMakeFaces null PC"); // jyl980402+ Standard_Real tol = Max(tolE,tolpc); // jyl980402+ BRep_Builder BB_PC; BB_PC.UpdateEdge(newEdge,C2D,newFace,tol); // jyl980402+ } // jyl980402+ } // FABU.MoreEdge() //--ofv: if((neINTERNAL == 0 && neEXTERNAL == 0) || (ne == neINTERNAL || ne == neEXTERNAL)) { TopExp_Explorer EdgeEx; if(nbw == 1 && ne == 2) { EdgeEx.Init(CmpOfEdges,TopAbs_EDGE); TopoDS_Edge nEdge1 = TopoDS::Edge(EdgeEx.Current()); EdgeEx.Next(); TopoDS_Edge nEdge2 = TopoDS::Edge(EdgeEx.Current()); if( nEdge1.IsSame(nEdge2) ) return; } for(EdgeEx.Init(CmpOfEdges,TopAbs_EDGE); EdgeEx.More(); EdgeEx.Next()) { TopoDS_Edge newEdge = TopoDS::Edge(EdgeEx.Current()); FABU.AddEdgeWire(newEdge,newWire); } } else { //TopTools_IndexedDataMapOfShapeListOfShape mapVOE; mapVOE.Clear(); TopExp::MapShapesAndAncestors(CmpOfEdges,TopAbs_VERTEX,TopAbs_EDGE,mapVOE); // checking: wire is closed and regular. If wire is not close or not regular: vertex has only the one edge // or vetrex has more then two shared edges, we don't modify it. Standard_Boolean WisClsd = Standard_True; for(Standard_Integer MapStep = 1; MapStep <= mapVOE.Extent(); MapStep++) { const TopTools_ListOfShape& LofE = mapVOE.FindFromIndex(MapStep); if(LofE.Extent() != 2) { WisClsd = Standard_False; break; } } if(!WisClsd) { //wire is not regular: TopExp_Explorer EdgeEx; for(EdgeEx.Init(CmpOfEdges,TopAbs_EDGE); EdgeEx.More(); EdgeEx.Next()) { TopoDS_Edge newEdge = TopoDS::Edge(EdgeEx.Current()); FABU.AddEdgeWire(newEdge,newWire); } } else { //wire seems to be regular: TopTools_ListOfShape LofAddE; // list of edges has already been added in wire Standard_Integer naddsame = 0; while( ne > (LofAddE.Extent() + naddsame) ) { for(Standard_Integer StepMap = 1; StepMap <= mapVOE.Extent(); StepMap++) { const TopTools_ListOfShape& LofE = mapVOE.FindFromIndex(StepMap); TopTools_ListIteratorOfListOfShape itLofE(LofE); TopoDS_Edge E1 = TopoDS::Edge(itLofE.Value()); itLofE.Next(); TopoDS_Edge E2 = TopoDS::Edge(itLofE.Value()); TopAbs_Orientation O1 = E1.Orientation(); TopAbs_Orientation O2 = E2.Orientation(); Standard_Boolean IsSameE1 = BRep_Tool::IsClosed(E1,tdF); Standard_Boolean IsSameE2 = BRep_Tool::IsClosed(E2,tdF); Standard_Boolean AddE1 = Standard_True; Standard_Boolean AddE2 = Standard_True; //checking current edges in the list of added edges TopTools_ListIteratorOfListOfShape itLofAddE(LofAddE); for(; itLofAddE.More(); itLofAddE.Next() ) { const TopoDS_Shape& LE = itLofAddE.Value(); TopAbs_Orientation OLE = LE.Orientation(); if(E1.IsSame(LE) && !IsSameE1) { AddE1 = Standard_False; E1.Orientation(OLE); O1 = OLE; } if(E2.IsSame(LE) && !IsSameE2) { AddE2 = Standard_False; E2.Orientation(OLE); O2 = OLE; } } Standard_Integer chkORI = FUN_CheckORI(O1,O2); if(chkORI == 0){ AddE1 = Standard_False; AddE2 = Standard_False; } if(chkORI == 1) { TopAbs_Orientation ori = FUN_ReOrientIntExtEdge(E2,O2,E1); if(ori == TopAbs_FORWARD) { E1.Orientation(TopAbs_FORWARD); neFORWARD++; } if(ori == TopAbs_REVERSED){ E1.Orientation(TopAbs_REVERSED); neREVERSED++; } if(ori == TopAbs_REVERSED || ori == TopAbs_FORWARD) { if(O1 == TopAbs_INTERNAL) neINTERNAL--; else neEXTERNAL--; } } if(chkORI == 2) { TopAbs_Orientation ori = FUN_ReOrientIntExtEdge(E1,O1,E2); if(ori == TopAbs_FORWARD) { E2.Orientation(TopAbs_FORWARD); neFORWARD++; } if(ori == TopAbs_REVERSED){ E2.Orientation(TopAbs_REVERSED); neREVERSED++; } if(ori == TopAbs_REVERSED || ori == TopAbs_FORWARD) { if(O2 == TopAbs_INTERNAL) neINTERNAL--; else neEXTERNAL--; } } if(AddE1) { FABU.AddEdgeWire(E1,newWire); if(!IsSameE1) LofAddE.Append(E1); else naddsame++; } if(AddE2) { FABU.AddEdgeWire(E2,newWire); if(!IsSameE2) LofAddE.Append(E2); else naddsame++; } }//for StepMap } // while ne > } // not regular } // neINTERNAL(neEXTERNAL) != 0 } // !isold //--ofv. #ifdef OCCT_DEBUG if ( tSPS ) cout<<"#--- GFABUMakeFaces "< is empty : if ( !isold ) { if (ne == 0) continue; else if (nbw == 1 && (ne == neINTERNAL+neEXTERNAL)) continue; else nbnewWwithe++; } // caractere Closed() du nouveau wire newWire if ( !isold ) { Standard_Boolean closed = FUN_tool_ClosedW(newWire); myBuildTool.Closed(newWire,closed); } // !isold myBuildTool.AddFaceWire(newFace,newWire); } // FABU.MoreWire() if ( nbnewWwithe == 0 && nboldW == 0 ) { continue; } Standard_Boolean topurge = FUN_purgeFon1nonoriE(newFace); if (topurge) { continue; } // Le changement de surface de trim a basis causait la perte des regularites de l'edge // j'ai change par un recadrage du trim en attendant mieux. DPF le 29/07/1998. // Le danger est de modifier une donnee d'entree. Handle(Standard_Type) T = Surf->DynamicType(); Standard_Boolean istrim = ( T == STANDARD_TYPE(Geom_RectangularTrimmedSurface) ); if (istrim) { Handle(Geom_RectangularTrimmedSurface) hrts=Handle(Geom_RectangularTrimmedSurface)::DownCast (Surf); Standard_Real oumin,oumax,ovmin,ovmax; hrts->Bounds(oumin,oumax,ovmin,ovmax); Standard_Real umin,umax,vmin,vmax; BRepTools::UVBounds(newFace, umin, umax, vmin, vmax); if (umin < oumin) oumin=umin; if (umax > oumax) oumax=umax; if (vmin < ovmin) ovmin=vmin; if (vmax > ovmax) ovmax=vmax; hrts->SetTrim(oumin, oumax, ovmin, ovmax, Standard_True, Standard_True); } lnewFace.Append(newFace); } // FABU.MoreFace() #ifdef OCCT_DEBUG if(tSPS) { cout<