-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
// File: BlockFix_UnionFaces.cxx
// Created: Tue Dec 7 17:15:42 2004
#include <BlockFix_UnionFaces.hxx>
-#include <Basics_OCCTVersion.hxx>
-
#include <ShapeAnalysis_WireOrder.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeFix_Wire.hxx>
#include <ShapeFix_Edge.hxx>
-#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
#include <IntPatch_ImpImpIntersection.hxx>
-#else
-#include <IntPatch_TheIIIntOfIntersection.hxx>
-#endif
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
//=======================================================================
//function : AddOrdinaryEdges
-//purpose : auxilary
+//purpose : auxiliary
// adds edges from the shape to the sequence
// seams and equal edges are dropped
// Returns true if one of original edges dropped
{
//map of edges
TopTools_MapOfShape aNewEdges;
+ TopExp_Explorer exp(aShape,TopAbs_EDGE);
//add edges without seams
- for(TopExp_Explorer exp(aShape,TopAbs_EDGE); exp.More(); exp.Next()) {
+ for(; exp.More(); exp.Next()) {
TopoDS_Shape edge = exp.Current();
if(aNewEdges.Contains(edge))
aNewEdges.Remove(edge);
}
}
- //add edges to the sequemce
- for(TopTools_MapIteratorOfMapOfShape anIter(aNewEdges); anIter.More(); anIter.Next())
- edges.Append(anIter.Key());
+ //add edges to the sequence
+ for(exp.ReInit(); exp.More(); exp.Next()) {
+ const TopoDS_Shape &anEdge = exp.Current();
+
+ if (aNewEdges.Contains(anEdge)) {
+ edges.Append(anEdge);
+ }
+ }
return isDropped;
}
//=======================================================================
//function : ClearRts
-//purpose : auxilary
+//purpose : auxiliary
//=======================================================================
static Handle(Geom_Surface) ClearRts(const Handle(Geom_Surface)& aSurface)
{
return aSurface;
}
+//=======================================================================
+//function : IsFacesOfSameSolids
+//purpose : auxiliary
+//=======================================================================
+static Standard_Boolean IsFacesOfSameSolids
+ (const TopoDS_Face &theFace1,
+ const TopoDS_Face &theFace2,
+ const TopTools_IndexedDataMapOfShapeListOfShape &theMapFaceSolids)
+{
+ Standard_Boolean isSame = Standard_False;
+
+ if (theMapFaceSolids.Contains(theFace1) &&
+ theMapFaceSolids.Contains(theFace2)) {
+ const TopTools_ListOfShape& aList1 = theMapFaceSolids.FindFromKey(theFace1);
+ const TopTools_ListOfShape& aList2 = theMapFaceSolids.FindFromKey(theFace2);
+
+ if (aList1.Extent() == aList2.Extent()) {
+ TopTools_ListIteratorOfListOfShape anIter1(aList1);
+
+ isSame = Standard_True;
+
+ for (; anIter1.More(); anIter1.Next()) {
+ const TopoDS_Shape &aSolid1 = anIter1.Value();
+ TopTools_ListIteratorOfListOfShape anIter2(aList2);
+
+ for (; anIter2.More(); anIter2.Next()) {
+ if (aSolid1.IsSame(anIter2.Value())) {
+ // Same solid is detected. Break the loop
+ break;
+ }
+ }
+
+ if (!anIter2.More()) {
+ // No same solid is detected. Break the loop.
+ isSame = Standard_False;
+ break;
+ }
+ }
+ }
+ }
+
+ return isSame;
+}
+
+//=======================================================================
+//function : IsEdgeValidToMerge
+//purpose : Edge is valid if it is not seam or if it is a seam and the face
+// has another seam edge.
+//=======================================================================
+static Standard_Boolean IsEdgeValidToMerge(const TopoDS_Edge &theEdge,
+ const TopoDS_Face &theFace)
+{
+ Standard_Boolean isValid = Standard_True;
+
+ if (BRep_Tool::IsClosed(theEdge, theFace)) {
+ // This is a seam edge. Check if there are another seam edges on the face.
+ TopExp_Explorer anExp(theFace, TopAbs_EDGE);
+
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &aShEdge = anExp.Current();
+
+ // Skip same edge.
+ if (theEdge.IsSame(aShEdge)) {
+ continue;
+ }
+
+ // Check if this edge is a seam.
+ TopoDS_Edge anEdge = TopoDS::Edge(aShEdge);
+
+ if (BRep_Tool::IsClosed(anEdge, theFace)) {
+ isValid = Standard_False;
+ break;
+ }
+ }
+ }
+
+ return isValid;
+}
+
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
{
- Handle(ShapeBuild_ReShape) myContext = new ShapeBuild_ReShape;
- TopoDS_Shape aResShape = myContext->Apply(Shape);
+ // Fill Map of faces as keys and list of solids or shells as items.
+ TopTools_IndexedDataMapOfShapeListOfShape aMapFaceSoOrSh;
+
+ TopAbs_ShapeEnum aType = Shape.ShapeType();
+
+ if (aType != TopAbs_SHELL) {
+ aType = TopAbs_SOLID;
+ }
+
+ TopExp::MapShapesAndAncestors
+ (Shape, TopAbs_FACE, aType, aMapFaceSoOrSh);
// processing each solid
+ Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
+ TopTools_MapOfShape aProcessed;
TopExp_Explorer exps;
- for (exps.Init(Shape, TopAbs_SOLID); exps.More(); exps.Next()) {
- TopoDS_Solid aSolid = TopoDS::Solid(exps.Current());
+ for (exps.Init(Shape, aType); exps.More(); exps.Next()) {
+ TopoDS_Shape aSoOrSh = exps.Current();
// creating map of edge faces
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
- TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
-
- // map of processed shapes
- TopTools_MapOfShape aProcessed;
-
- Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
+ TopExp::MapShapesAndAncestors(aSoOrSh, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
Standard_Integer NbModif = 0;
Standard_Boolean hasFailed = Standard_False;
int nbf = 0;
TopExp_Explorer exp;
TopTools_MapOfShape mapF;
- for (exp.Init(aSolid, TopAbs_FACE); exp.More(); exp.Next()) {
+ for (exp.Init(aSoOrSh, TopAbs_FACE); exp.More(); exp.Next()) {
if (mapF.Add(exp.Current()))
nbf++;
}
// processing each face
mapF.Clear();
- for (exp.Init(aSolid, TopAbs_FACE); exp.More() && doUnion; exp.Next()) {
+ for (exp.Init(aSoOrSh, TopAbs_FACE); exp.More() && doUnion; exp.Next()) {
TopoDS_Face aFace = TopoDS::Face(exp.Current().Oriented(TopAbs_FORWARD));
- if (aProcessed.Contains(aFace))
+ if (aProcessed.Contains(aFace)) {
continue;
+ }
Standard_Integer dummy;
TopTools_SequenceOfShape edges;
TopLoc_Location aBaseLocation;
Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(aFace,aBaseLocation);
aBaseSurface = ClearRts(aBaseSurface);
+ aBaseSurface = Handle(Geom_Surface)::DownCast(aBaseSurface->Copy());
// find adjacent faces to union
Standard_Integer i;
for (i = 1; i <= edges.Length(); i++) {
TopoDS_Edge edge = TopoDS::Edge(edges(i));
- if (BRep_Tool::Degenerated(edge))
+ if (BRep_Tool::Degenerated(edge) || !IsEdgeValidToMerge(edge, aFace))
continue;
const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
if (aProcessed.Contains(anCheckedFace))
continue;
+ if (!IsEdgeValidToMerge(edge, anCheckedFace)) {
+ // Skip seam edge.
+ continue;
+ }
+
+ // Check if faces belong to same solids.
+ if (!IsFacesOfSameSolids(aFace, anCheckedFace, aMapFaceSoOrSh)) {
+ continue;
+ }
+
if (IsSameDomain(aFace,anCheckedFace)) {
if (aList.Extent() != 2) {
// sorting any type of edges
aWire = TopoDS::Wire(aContext->Apply(aWire));
- TopoDS_Face tmpF = TopoDS::Face(aContext->Apply(faces(1).Oriented(TopAbs_FORWARD)));
- Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(aWire,tmpF,Precision::Confusion());
+ Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(aWire,aResult,Precision::Confusion());
sfw->FixReorder();
Standard_Boolean isDegRemoved = Standard_False;
if(!sfw->StatusReorder ( ShapeExtend_FAIL )) {
Standard_Real f,l;
//smh protection on NULL pcurve
Handle(Geom2d_Curve) c2d;
- if(!sae.PCurve(sbwd->Edge(j),tmpF,c2d,f,l)) {
+ if(!sae.PCurve(sbwd->Edge(j),aResult,c2d,f,l)) {
aLastEdge--;
continue;
}
gp_XY aVec = anEnd-aStart;
Handle(Geom2d_Line) aLine = new Geom2d_Line(aStart,gp_Dir2d(anEnd-aStart));
- B.UpdateEdge(E,aLine,tmpF,0.);
- B.Range(E,tmpF,0.,aVec.Modulus());
+ B.UpdateEdge(E,aLine,aResult,0.);
+ B.Range(E,aResult,0.,aVec.Modulus());
Handle(Geom_Curve) C3d;
B.UpdateEdge(E,C3d,0.);
B.Degenerated(E,Standard_True);
//TopoDS_Shape aResult = Shape;
if (NbModif > 0 && !hasFailed) {
- TopoDS_Shape aResult = aContext->Apply(aSolid);
+ TopoDS_Shape aResult = aContext->Apply(aSoOrSh);
ShapeFix_Edge sfe;
for (exp.Init(aResult,TopAbs_EDGE); exp.More(); exp.Next()) {
// ptv add fix same parameter
sfe.FixSameParameter(E, myTolerance);
}
-
- myContext->Replace(aSolid, aResult);
}
- //else
- {
- for (exp.Init(aSolid, TopAbs_FACE); exp.More(); exp.Next()) {
- TopoDS_Face aFace = TopoDS::Face(exp.Current().Oriented(TopAbs_FORWARD));
- Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
- sfw->SetContext(myContext);
- sfw->SetPrecision(myTolerance);
- sfw->SetMinTolerance(myTolerance);
- sfw->SetMaxTolerance(Max(1.,myTolerance*1000.));
- sfw->SetFace(aFace);
- for (TopoDS_Iterator iter (aFace,Standard_False); iter.More(); iter.Next()) {
+
+ for (exp.Init(aSoOrSh, TopAbs_FACE); exp.More(); exp.Next()) {
+ TopoDS_Face aFace = TopoDS::Face(exp.Current().Oriented(TopAbs_FORWARD));
+ Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire;
+ sfw->SetContext(aContext);
+ sfw->SetPrecision(myTolerance);
+ sfw->SetMinTolerance(myTolerance);
+ sfw->SetMaxTolerance(Max(1.,myTolerance*1000.));
+ sfw->SetFace(aFace);
+ for (TopoDS_Iterator iter (aFace,Standard_False); iter.More(); iter.Next()) {
+ TopoDS_Shape aFaceCont = iter.Value();
+ if (!aFaceCont.IsNull() && aFaceCont.ShapeType() == TopAbs_WIRE) {
TopoDS_Wire wire = TopoDS::Wire(iter.Value());
sfw->Load(wire);
sfw->FixReorder();
}
} // end processing each solid
- aResShape = myContext->Apply(Shape);
+ const TopoDS_Shape aResShape = aContext->Apply(Shape);
+
return aResShape;
}
Handle(BRepTopAdaptor_TopolTool) aTT2 = new BRepTopAdaptor_TopolTool();
try {
-#if OCC_VERSION_LARGE > 0x06010000
OCC_CATCH_SIGNALS;
-#endif
-#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
IntPatch_ImpImpIntersection anIIInt (aGA1, aTT1, aGA2, aTT2, aPrec, aPrec);
-#else
- IntPatch_TheIIIntOfIntersection anIIInt (aGA1, aTT1, aGA2, aTT2, aPrec, aPrec);
-#endif
+
if (!anIIInt.IsDone() || anIIInt.IsEmpty())
return false;