mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Implementation of the algorithm for replacing faces in shape with new faces based on other surfaces - BRepOffsetAPI_PatchFaces.
The algorithm runs the steps similar to 3d Offset algorithm for Join type Intersection (intersection of the faces with neighbors for trimming of the faces by the adjacent faces). Test cases for new functionality.
This commit is contained in:
@@ -2817,7 +2817,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
|
||||
const Standard_Boolean GlobalEnlargeVfirst,
|
||||
const Standard_Boolean GlobalEnlargeVlast)
|
||||
{
|
||||
const Standard_Real coeff = 4.;
|
||||
const Standard_Real coeff = 2.;
|
||||
const Standard_Real TolApex = 1.e-5;
|
||||
|
||||
Standard_Boolean SurfaceChange = Standard_False;
|
||||
@@ -3200,7 +3200,8 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
|
||||
const Standard_Boolean UpdatePCurve,
|
||||
const Standard_Boolean enlargeU,
|
||||
const Standard_Boolean enlargeVfirst,
|
||||
const Standard_Boolean enlargeVlast)
|
||||
const Standard_Boolean enlargeVlast,
|
||||
const Standard_Boolean UseInfini)
|
||||
{
|
||||
//---------------------------
|
||||
// extension de la geometrie.
|
||||
@@ -3223,8 +3224,20 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
|
||||
}
|
||||
|
||||
S->Bounds (US1,US2,VS1,VS2);
|
||||
UU1 = VV1 = - infini;
|
||||
UU2 = VV2 = infini;
|
||||
if (UseInfini)
|
||||
{
|
||||
UU1 = VV1 = - infini;
|
||||
UU2 = VV2 = infini;
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Real FaceDU = UF2 - UF1;
|
||||
Standard_Real FaceDV = VF2 - VF1;
|
||||
UU1 = UF1 - FaceDU;
|
||||
UU2 = UF2 + FaceDU;
|
||||
VV1 = VF1 - FaceDV;
|
||||
VV2 = VF2 + FaceDV;
|
||||
}
|
||||
|
||||
if (CanExtentSurface) {
|
||||
SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
|
||||
|
@@ -92,8 +92,15 @@ public:
|
||||
//! if <UpdatePCurve> is TRUE, update the pcurves of the
|
||||
//! edges of <F> on the new surface.if the surface has been changed,
|
||||
//! Returns True if The Surface of <NF> has changed.
|
||||
Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F, TopoDS_Face& NF, const Standard_Boolean ChangeGeom, const Standard_Boolean UpDatePCurve = Standard_False, const Standard_Boolean enlargeU = Standard_True, const Standard_Boolean enlargeVfirst = Standard_True, const Standard_Boolean enlargeVlast = Standard_True);
|
||||
|
||||
Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F,
|
||||
TopoDS_Face& NF,
|
||||
const Standard_Boolean ChangeGeom,
|
||||
const Standard_Boolean UpDatePCurve = Standard_False,
|
||||
const Standard_Boolean enlargeU = Standard_True,
|
||||
const Standard_Boolean enlargeVfirst = Standard_True,
|
||||
const Standard_Boolean enlargeVlast = Standard_True,
|
||||
const Standard_Boolean UseInfini = Standard_True);
|
||||
|
||||
Standard_EXPORT static void ExtentFace (const TopoDS_Face& F, TopTools_DataMapOfShapeShape& ConstShapes, TopTools_DataMapOfShapeShape& ToBuild, const TopAbs_State Side, const Standard_Real TolConf, TopoDS_Face& NF);
|
||||
|
||||
//! Via the wire explorer store in <NOnV1> for
|
||||
|
781
src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx
Normal file
781
src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx
Normal file
@@ -0,0 +1,781 @@
|
||||
// Created on: 2012-08-06
|
||||
// Created by: jgv@ROLEX
|
||||
// Copyright (c) 2012-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 <BRepOffsetAPI_PatchFaces.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepAdaptor_HSurface.hxx>
|
||||
#include <BRepTopAdaptor_TopolTool.hxx>
|
||||
#include <LocalAnalysis_SurfaceContinuity.hxx>
|
||||
#include <TopOpeBRepTool_TOOL.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <BRepLib_MakeVertex.hxx>
|
||||
#include <BRepLib_MakeEdge.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <IntTools_Context.hxx>
|
||||
#include <BOPTools_AlgoTools.hxx>
|
||||
#include <BRepOffset_Tool.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
|
||||
#include <BRepAlgoAPI_Section.hxx>
|
||||
#include <Extrema_ExtPC.hxx>
|
||||
#include <BRepExtrema_ExtCC.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
|
||||
|
||||
static TopoDS_Edge MakeNewEdgeWithOldPcurvesOnNewSurfaces(const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Face& theOldFace1,
|
||||
const TopoDS_Face& theNewFace1,
|
||||
const TopoDS_Face& theOldFace2,
|
||||
const TopoDS_Face& theNewFace2)
|
||||
{
|
||||
TopoDS_Edge aNewEdge;
|
||||
Standard_Real fpar, lpar;
|
||||
BRep_Builder BB;
|
||||
|
||||
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar);
|
||||
aNewEdge = BRepLib_MakeEdge(aCurve, aCurve->FirstParameter(), aCurve->LastParameter()); //???
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(aNewEdge, V1, V2);
|
||||
aNewEdge.Free(Standard_True);
|
||||
BB.Remove(aNewEdge, V1);
|
||||
BB.Remove(aNewEdge, V2);
|
||||
|
||||
Standard_Real Etol = BRep_Tool::Tolerance(theEdge);
|
||||
Handle(Geom2d_Curve) aPCurve1 = BRep_Tool::CurveOnSurface(theEdge, theOldFace1, fpar, lpar);
|
||||
BB.UpdateEdge(aNewEdge, aPCurve1, theNewFace1, Etol);
|
||||
Handle(Geom2d_Curve) aPCurve2 = BRep_Tool::CurveOnSurface(theEdge, theOldFace2, fpar, lpar);
|
||||
BB.UpdateEdge(aNewEdge, aPCurve2, theNewFace2, Etol);
|
||||
|
||||
return aNewEdge;
|
||||
}
|
||||
|
||||
static void UpdateEdgeByProjectionOfPCurve(TopoDS_Edge& anEdge,
|
||||
const TopoDS_Face& aNewFace,
|
||||
const TopoDS_Face& aBoundedNewFace)
|
||||
{
|
||||
BRep_Builder BB;
|
||||
Standard_Real fpar, lpar;
|
||||
|
||||
Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,fpar,lpar);
|
||||
|
||||
Handle(Geom_Surface) NewSurf = BRep_Tool::Surface(aNewFace);
|
||||
Handle(ShapeAnalysis_Surface) SAS = new ShapeAnalysis_Surface(NewSurf);
|
||||
ShapeConstruct_ProjectCurveOnSurface aToolProj;
|
||||
aToolProj.Init(SAS, Precision::Confusion());
|
||||
Handle(Geom2d_Curve) NewPCurve;
|
||||
aToolProj.Perform(aCurve,fpar,lpar,NewPCurve);
|
||||
Standard_Real TolReached = SAS->Gap();
|
||||
//BB.UpdateEdge(anEdge, NullPCurve, aFace, 0.);
|
||||
BB.UpdateEdge(anEdge, NewPCurve, aBoundedNewFace, TolReached);
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(anEdge, V1, V2);
|
||||
BB.UpdateVertex(V1, TolReached);
|
||||
BB.UpdateVertex(V2, TolReached);
|
||||
}
|
||||
|
||||
static void ProjectVertexOnNewEdge(const TopoDS_Vertex& theVertex,
|
||||
const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Edge& theNewEdge,
|
||||
Standard_Real& theParam,
|
||||
gp_Pnt& thePnt,
|
||||
Standard_Real& theTolReached)
|
||||
{
|
||||
Standard_Real ParamOnEdge = BRep_Tool::Parameter(theVertex, theEdge);
|
||||
BRepAdaptor_Curve BAcurve(theEdge);
|
||||
BRepAdaptor_Curve BAnewcurve(theNewEdge);
|
||||
gp_Pnt PointOnEdge = BAcurve.Value(ParamOnEdge);
|
||||
Extrema_ExtPC Projector(PointOnEdge, BAnewcurve);
|
||||
Standard_Real Param[4], dist[4];
|
||||
gp_Pnt Pnt[4];
|
||||
Param[1] = BAnewcurve.FirstParameter();
|
||||
Param[2] = BAnewcurve.LastParameter();
|
||||
Projector.TrimmedSquareDistances(dist[1], dist[2], Pnt[1], Pnt[2]);
|
||||
dist[3] = RealLast();
|
||||
if (Projector.IsDone() && Projector.NbExt() > 0)
|
||||
{
|
||||
Standard_Integer imin = 1;
|
||||
for (Standard_Integer i = 2; i <= Projector.NbExt(); i++)
|
||||
if (Projector.SquareDistance(i) < Projector.SquareDistance(imin))
|
||||
imin = i;
|
||||
Param[3] = Projector.Point(imin).Parameter();
|
||||
dist[3] = Projector.SquareDistance(imin);
|
||||
Pnt[3] = Projector.Point(imin).Value();
|
||||
}
|
||||
|
||||
Standard_Integer imin = 1;
|
||||
for (Standard_Integer i = 2; i <= 3; i++)
|
||||
if (dist[i] < dist[imin])
|
||||
imin = i;
|
||||
|
||||
theParam = Param[imin];
|
||||
thePnt = Pnt[imin];
|
||||
theTolReached = sqrt(dist[imin]);
|
||||
}
|
||||
|
||||
static TopoDS_Edge GetGeneratedEdge(const TopoDS_Edge& anEdge,
|
||||
const TopoDS_Face& aFace,
|
||||
const TopoDS_Face& aNewFace)
|
||||
{
|
||||
TopoDS_Edge aNewEdge;
|
||||
|
||||
TopExp_Explorer Explo(aFace, TopAbs_EDGE);
|
||||
TopExp_Explorer ExploNew(aNewFace, TopAbs_EDGE);
|
||||
for (; Explo.More(); Explo.Next(),ExploNew.Next())
|
||||
{
|
||||
const TopoDS_Shape& EdgeInFace = Explo.Current();
|
||||
//const TopoDS_Shape& EdgeInNewFace = ExploNew.Current();
|
||||
if (anEdge == EdgeInFace)
|
||||
{
|
||||
aNewEdge = TopoDS::Edge(ExploNew.Current());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(aNewEdge, V1, V2);
|
||||
BRep_Builder BB;
|
||||
aNewEdge.Free(Standard_True);
|
||||
BB.Remove(aNewEdge, V1);
|
||||
BB.Remove(aNewEdge, V2);
|
||||
return aNewEdge;
|
||||
}
|
||||
|
||||
static TopAbs_Orientation OrientationInEdge(const TopoDS_Vertex& theVertex,
|
||||
const TopoDS_Edge& theEdge)
|
||||
{
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(theEdge, V1, V2);
|
||||
if (theVertex.IsSame(V1))
|
||||
return TopAbs_FORWARD;
|
||||
|
||||
return TopAbs_REVERSED;
|
||||
}
|
||||
|
||||
static Standard_Boolean EdgeContains(const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Vertex& theVertex)
|
||||
{
|
||||
TopoDS_Iterator ite(theEdge);
|
||||
for (; ite.More(); ite.Next())
|
||||
if (theVertex.IsSame(ite.Value()))
|
||||
return Standard_True;
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
|
||||
static Standard_Boolean IsTangentFaces(const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Face& theFace1,
|
||||
const TopoDS_Face& theFace2,
|
||||
const GeomAbs_Shape Order)
|
||||
{
|
||||
if (Order == GeomAbs_G1 &&
|
||||
BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
|
||||
return Standard_True;
|
||||
|
||||
Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
|
||||
|
||||
Standard_Real aFirst;
|
||||
Standard_Real aLast;
|
||||
|
||||
// Obtaining of pcurves of edge on two faces.
|
||||
const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
|
||||
(theEdge, theFace1, aFirst, aLast);
|
||||
const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
|
||||
(theEdge, theFace2, aFirst, aLast);
|
||||
if (aC2d1.IsNull() || aC2d2.IsNull())
|
||||
return Standard_False;
|
||||
|
||||
// Obtaining of two surfaces from adjacent faces.
|
||||
Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
|
||||
Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
|
||||
|
||||
if (aSurf1.IsNull() || aSurf2.IsNull())
|
||||
return Standard_False;
|
||||
|
||||
// Computation of the number of samples on the edge.
|
||||
BRepAdaptor_Surface aBAS1(theFace1);
|
||||
BRepAdaptor_Surface aBAS2(theFace2);
|
||||
Handle(BRepAdaptor_HSurface) aBAHS1 = new BRepAdaptor_HSurface(aBAS1);
|
||||
Handle(BRepAdaptor_HSurface) aBAHS2 = new BRepAdaptor_HSurface(aBAS2);
|
||||
Handle(BRepTopAdaptor_TopolTool) aTool1 = new BRepTopAdaptor_TopolTool(aBAHS1);
|
||||
Handle(BRepTopAdaptor_TopolTool) aTool2 = new BRepTopAdaptor_TopolTool(aBAHS2);
|
||||
Standard_Integer aNbSamples1 = aTool1->NbSamples();
|
||||
Standard_Integer aNbSamples2 = aTool2->NbSamples();
|
||||
const Standard_Integer aNbSamplesMax = 23;
|
||||
Standard_Integer aNbSamples = Min(aNbSamplesMax, Max(aNbSamples1, aNbSamples2));
|
||||
const Standard_Real aTolAngle = M_PI/18;
|
||||
|
||||
|
||||
// Computation of the continuity.
|
||||
Standard_Real aPar;
|
||||
Standard_Real aDelta = (aLast - aFirst)/(aNbSamples - 1);
|
||||
Standard_Integer i, nbNotDone = 0;
|
||||
|
||||
for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
|
||||
if (i == aNbSamples) aPar = aLast;
|
||||
|
||||
LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar,
|
||||
aSurf1, aSurf2, Order,
|
||||
0.001, TolC0, aTolAngle, 0.1, 0.1);
|
||||
if (!aCont.IsDone())
|
||||
{
|
||||
nbNotDone++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Order == GeomAbs_G1)
|
||||
{
|
||||
if (!aCont.IsG1())
|
||||
return Standard_False;
|
||||
}
|
||||
else if (!aCont.IsG2())
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (nbNotDone == aNbSamples)
|
||||
return Standard_False;
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : BRepOffsetAPI_PatchFaces
|
||||
//purpose : Constructor
|
||||
//=======================================================================
|
||||
|
||||
BRepOffsetAPI_PatchFaces::BRepOffsetAPI_PatchFaces(const TopoDS_Shape& theShape)
|
||||
{
|
||||
myInitialShape = theShape;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetOffsetFace
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BRepOffsetAPI_PatchFaces::AddPatchFace(const TopoDS_Face& theFace,
|
||||
const TopoDS_Face& thePatchFace)
|
||||
{
|
||||
// Check the orientation of the patch face and make
|
||||
// it oriented the same way as original
|
||||
TopoDS_Face aFace = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD));
|
||||
TopoDS_Face aPatchFace = TopoDS::Face(thePatchFace.Oriented(TopAbs_FORWARD));
|
||||
|
||||
Handle(IntTools_Context) aCtx = new IntTools_Context;
|
||||
Standard_Boolean bToReverse = BOPTools_AlgoTools::IsSplitToReverse(aFace, aPatchFace, aCtx);
|
||||
TopoDS_Face anOrientedPatchFace = bToReverse ? TopoDS::Face(aPatchFace.Reversed()) : aPatchFace;
|
||||
myFacePatchFace.Add(aFace, anOrientedPatchFace);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Build
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void BRepOffsetAPI_PatchFaces::Build()
|
||||
{
|
||||
TopExp::MapShapesAndUniqueAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, myEFmap);
|
||||
|
||||
//Draft filling of <myFaceNewFace>
|
||||
for (Standard_Integer i = 1; i <= myFacePatchFace.Extent(); i++)
|
||||
{
|
||||
const TopoDS_Face& aFace = TopoDS::Face(myFacePatchFace.FindKey(i));
|
||||
const TopoDS_Shape& aPatchFace = myFacePatchFace(i);
|
||||
myFaceNewFace.Add(aFace, aPatchFace);
|
||||
TopExp_Explorer Explo(aFace, TopAbs_EDGE);
|
||||
for (; Explo.More(); Explo.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
|
||||
const TopTools_ListOfShape& Lfaces = myEFmap.FindFromKey(anEdge);
|
||||
TopoDS_Face aNeighborFace = (aFace.IsSame(Lfaces.First()))?
|
||||
TopoDS::Face(Lfaces.Last()) : TopoDS::Face(Lfaces.First());
|
||||
if (myFacePatchFace.Contains(aNeighborFace))
|
||||
continue;
|
||||
if (myFaceNewFace.Contains(aNeighborFace))
|
||||
continue;
|
||||
Standard_Boolean IsTangentEdge = IsTangentFaces(anEdge, aFace, aNeighborFace, GeomAbs_G1);
|
||||
if (IsTangentEdge)
|
||||
{
|
||||
myTangentEdges.Add(anEdge);
|
||||
continue;
|
||||
}
|
||||
|
||||
aNeighborFace.Orientation(TopAbs_FORWARD);
|
||||
TopoDS_Face aNewFace;
|
||||
BRepOffset_Tool::EnLargeFace(aNeighborFace, aNewFace,
|
||||
Standard_True,Standard_True,Standard_True,Standard_True,Standard_True,
|
||||
Standard_False); //not too big
|
||||
myFaceNewFace.Add(aNeighborFace, aNewFace);
|
||||
}
|
||||
}
|
||||
|
||||
//Make draft intersection edges: draft filling of <myEdgeNewEdge>
|
||||
BRep_Builder BB;
|
||||
TopTools_MapOfShape UpdatedConstEdges;
|
||||
for (Standard_Integer i = 1; i <= myFaceNewFace.Extent(); i++)
|
||||
{
|
||||
TopoDS_Face aFace = TopoDS::Face(myFaceNewFace.FindKey(i));
|
||||
TopoDS_Face aNewFace = TopoDS::Face(myFaceNewFace(i));
|
||||
TopoDS_Face aBoundedNewFace;
|
||||
if (myNewFaceBoundedFace.IsBound(aNewFace))
|
||||
aBoundedNewFace = TopoDS::Face(myNewFaceBoundedFace(aNewFace));
|
||||
else
|
||||
{
|
||||
aBoundedNewFace = TopoDS::Face(aNewFace.EmptyCopied());
|
||||
myNewFaceBoundedFace.Bind(aNewFace, aBoundedNewFace);
|
||||
}
|
||||
|
||||
TopoDS_Iterator itf(aFace);
|
||||
for (; itf.More(); itf.Next())
|
||||
{
|
||||
const TopoDS_Wire& aWire = TopoDS::Wire(itf.Value());
|
||||
TopoDS_Wire F_Wire = TopoDS::Wire(aWire.Oriented(TopAbs_FORWARD));
|
||||
BRepTools_WireExplorer wexp(F_Wire, aFace);
|
||||
for (; wexp.More(); wexp.Next())
|
||||
{
|
||||
TopoDS_Edge anEdge = wexp.Current();
|
||||
Standard_Boolean ToReverse = Standard_False;
|
||||
TopoDS_Edge aNewEdge;
|
||||
if (myEdgeNewEdge.IsBound(anEdge))
|
||||
//aNewEdge = TopoDS::Edge(myEdgeNewEdge(anEdge));
|
||||
continue;
|
||||
|
||||
Handle(Geom2d_Curve) NullPCurve;
|
||||
Standard_Real fpar, lpar;
|
||||
|
||||
const TopTools_ListOfShape& Lfaces = myEFmap.FindFromKey(anEdge);
|
||||
if (Lfaces.Extent() == 1) //seam edge
|
||||
{
|
||||
cout<<endl<<"Seam edge or degenerated edge !!!"<<endl;
|
||||
TopoDS_Edge GeneratedEdge = GetGeneratedEdge(anEdge, aFace, aNewFace);
|
||||
myOrientedEdgeNewEdge.Bind(anEdge, GeneratedEdge);
|
||||
continue;
|
||||
}
|
||||
|
||||
TopoDS_Face aNeighborFace = (aFace.IsSame(Lfaces.First()))?
|
||||
TopoDS::Face(Lfaces.Last()) : TopoDS::Face(Lfaces.First());
|
||||
|
||||
if (myTangentEdges.Contains(anEdge)&&
|
||||
!UpdatedConstEdges.Contains(anEdge)) //project onto patch
|
||||
{
|
||||
UpdateEdgeByProjectionOfPCurve(anEdge, aNewFace, aBoundedNewFace);
|
||||
|
||||
//aNewEdge = anEdge;
|
||||
UpdatedConstEdges.Add(anEdge);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (myFaceNewFace.Contains(aNeighborFace))//intersect
|
||||
{
|
||||
TopoDS_Face aNewNeighborFace = TopoDS::Face(myFaceNewFace.FindFromKey(aNeighborFace));
|
||||
TopoDS_Face aBoundedNewNeighborFace;
|
||||
if (myNewFaceBoundedFace.IsBound(aNewNeighborFace))
|
||||
aBoundedNewNeighborFace = TopoDS::Face(myNewFaceBoundedFace(aNewNeighborFace));
|
||||
else
|
||||
{
|
||||
aBoundedNewNeighborFace = TopoDS::Face(aNewNeighborFace.EmptyCopied());
|
||||
myNewFaceBoundedFace.Bind(aNewNeighborFace, aBoundedNewNeighborFace);
|
||||
}
|
||||
|
||||
if (!myFacePatchFace.Contains(aFace) &&
|
||||
!myFacePatchFace.Contains(aNeighborFace) &&
|
||||
IsTangentFaces(anEdge, aFace, aNeighborFace, GeomAbs_G1)) //smooth edge
|
||||
{
|
||||
//make new edge with pcurves on new surfaces
|
||||
aNewEdge = MakeNewEdgeWithOldPcurvesOnNewSurfaces(anEdge,
|
||||
aFace, aBoundedNewFace,
|
||||
aNeighborFace, aBoundedNewNeighborFace);
|
||||
|
||||
myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD), aNewEdge);
|
||||
continue;
|
||||
}
|
||||
|
||||
BRepLib::BuildCurves3d(aNewFace);
|
||||
BRepLib::BuildCurves3d(aNewNeighborFace);
|
||||
|
||||
BRepAlgoAPI_Section SecBuilder(aNewFace, aNewNeighborFace, Standard_False);
|
||||
SecBuilder.Approximation(Standard_True);
|
||||
SecBuilder.ComputePCurveOn1(Standard_True);
|
||||
SecBuilder.ComputePCurveOn2(Standard_True);
|
||||
SecBuilder.Build();
|
||||
TopoDS_Shape aSection = SecBuilder.Shape();
|
||||
Standard_Boolean Success = Standard_True;
|
||||
TopExp_Explorer ExpSec(aSection, TopAbs_EDGE);
|
||||
if (ExpSec.More())
|
||||
aNewEdge = TopoDS::Edge(ExpSec.Current());
|
||||
else //no intersection
|
||||
{
|
||||
cout<<endl<<"No intersecion => smooth edge"<<endl;
|
||||
Success = Standard_False;
|
||||
}
|
||||
ExpSec.Next();
|
||||
if (ExpSec.More())
|
||||
{
|
||||
cout<<endl<<"More than one intersecion => smooth edge"<<endl;
|
||||
Success = Standard_False;
|
||||
}
|
||||
if (!Success) //a smooth edge with bigger angle
|
||||
{
|
||||
if (myFacePatchFace.Contains(aFace)) //project onto patch
|
||||
{
|
||||
UpdateEdgeByProjectionOfPCurve(anEdge, aNewFace, aBoundedNewFace);
|
||||
|
||||
//Remove neighbor face from <myFaceNewFace>
|
||||
myFaceNewFace.Swap(myFaceNewFace.FindIndex(aNeighborFace), myFaceNewFace.Extent());
|
||||
myFaceNewFace.RemoveLast();
|
||||
|
||||
myTangentEdges.Add(anEdge);
|
||||
UpdatedConstEdges.Add(anEdge);
|
||||
}
|
||||
else
|
||||
{
|
||||
aNewEdge = MakeNewEdgeWithOldPcurvesOnNewSurfaces(anEdge,
|
||||
aFace, aBoundedNewFace,
|
||||
aNeighborFace, aBoundedNewNeighborFace);
|
||||
myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD), aNewEdge);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
TopoDS_Vertex V1, V2;
|
||||
TopExp::Vertices(aNewEdge, V1, V2);
|
||||
aNewEdge.Free(Standard_True);
|
||||
BB.Remove(aNewEdge, V1);
|
||||
BB.Remove(aNewEdge, V2);
|
||||
aNewEdge.Orientation(TopAbs_FORWARD);
|
||||
|
||||
//Make pcurves on new surfaces
|
||||
Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(aNewEdge, aNewFace, fpar, lpar);
|
||||
BB.UpdateEdge(aNewEdge, NullPCurve, aNewFace, 0.);
|
||||
BB.UpdateEdge(aNewEdge, PCurve1, aBoundedNewFace, 0.);
|
||||
Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(aNewEdge, aNewNeighborFace, fpar, lpar);
|
||||
BB.UpdateEdge(aNewEdge, NullPCurve, aNewNeighborFace, 0.);
|
||||
BB.UpdateEdge(aNewEdge, PCurve2, aBoundedNewNeighborFace, 0.);
|
||||
|
||||
//Check orientation of new edge
|
||||
BRepAdaptor_Curve BAcurve(anEdge);
|
||||
BRepAdaptor_Curve BAnewcurve(aNewEdge);
|
||||
gp_Pnt FirstPnt, FirstNewPnt;
|
||||
gp_Vec DirOnCurve, DirOnNewCurve;
|
||||
BAcurve.D1(BAcurve.FirstParameter(), FirstPnt, DirOnCurve);
|
||||
Standard_Real ParamOnNewEdge = BAnewcurve.FirstParameter();
|
||||
Extrema_ExtPC Projector(FirstPnt, BAnewcurve);
|
||||
if (!Projector.IsDone() || Projector.NbExt() == 0)
|
||||
{
|
||||
cout<<endl<<"Define orientation of new edge: extrema point-curve is not done"<<endl;
|
||||
}
|
||||
if (Projector.IsDone() && Projector.NbExt() > 0)
|
||||
{
|
||||
Standard_Integer indmin = 1;
|
||||
for (Standard_Integer ind = 2; ind <= Projector.NbExt(); ind++)
|
||||
if (Projector.SquareDistance(ind) < Projector.SquareDistance(indmin))
|
||||
indmin = ind;
|
||||
ParamOnNewEdge = Projector.Point(indmin).Parameter();
|
||||
}
|
||||
BAnewcurve.D1(ParamOnNewEdge, FirstNewPnt, DirOnNewCurve);
|
||||
Standard_Real ScalProd = DirOnCurve * DirOnNewCurve;
|
||||
if (ScalProd < 0.)
|
||||
ToReverse = Standard_True;
|
||||
|
||||
myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD),
|
||||
(ToReverse)? aNewEdge.Oriented(TopAbs_REVERSED) : aNewEdge);
|
||||
} //intersect
|
||||
else //borders on constant face: change surface of pcurve on existing edge
|
||||
{
|
||||
Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar);
|
||||
//BB.UpdateEdge(anEdge, NullPCurve, aFace, 0.);
|
||||
BB.UpdateEdge(anEdge, aPCurve, aBoundedNewFace, 0.);
|
||||
|
||||
aNewEdge = anEdge;
|
||||
}
|
||||
} //for (; wexp.More(); wexp.Next())
|
||||
} //for (; itf.More(); itf.Next())
|
||||
} //for (Standard_Integer i = 1; i <= myFaceNewFace.Extent(); i++)
|
||||
|
||||
//Intersect edges and make new wires
|
||||
for (Standard_Integer i = 1; i <= myFaceNewFace.Extent(); i++)
|
||||
{
|
||||
TopoDS_Face aFace = TopoDS::Face(myFaceNewFace.FindKey(i));
|
||||
TopoDS_Shape aNewFace = myFaceNewFace(i);
|
||||
TopoDS_Face aBoundedNewFace = TopoDS::Face(myNewFaceBoundedFace(aNewFace));
|
||||
|
||||
TopoDS_Iterator itf(aFace);
|
||||
for (; itf.More(); itf.Next())
|
||||
{
|
||||
const TopoDS_Wire& aWire = TopoDS::Wire(itf.Value());
|
||||
TopAbs_Orientation aWireOr = aWire.Orientation();
|
||||
|
||||
TopoDS_Wire aNewWire;
|
||||
BB.MakeWire(aNewWire);
|
||||
|
||||
TopoDS_Wire F_Wire = TopoDS::Wire(aWire.Oriented(TopAbs_FORWARD));
|
||||
BRepTools_WireExplorer wexp(F_Wire, aFace);
|
||||
TopoDS_Vertex CurVertex = wexp.CurrentVertex();
|
||||
TopoDS_Edge FirstEdge = wexp.Current();
|
||||
TopoDS_Edge FirstNewEdge = FirstEdge;
|
||||
if (myOrientedEdgeNewEdge.IsBound(FirstEdge))
|
||||
FirstNewEdge = TopoDS::Edge(myOrientedEdgeNewEdge(FirstEdge));
|
||||
else if (myEdgeNewEdge.IsBound(FirstEdge))
|
||||
FirstNewEdge = TopoDS::Edge(myEdgeNewEdge(FirstEdge));
|
||||
TopoDS_Edge CurEdge, PrevEdge = FirstEdge;
|
||||
TopoDS_Edge CurNewEdge, PrevNewEdge = FirstNewEdge;
|
||||
wexp.Next();
|
||||
if (!wexp.More() && //only one edge in wire
|
||||
!myVertexNewVertex.IsBound(CurVertex))
|
||||
{
|
||||
TopoDS_Vertex CurNewVertex;
|
||||
if (myVertexNewVertex.IsBound(CurVertex))
|
||||
CurNewVertex = TopoDS::Vertex(myVertexNewVertex(CurVertex));
|
||||
|
||||
if (myEdgeNewEdge.IsBound(FirstEdge))//new edge: update
|
||||
{
|
||||
Standard_Real fpar, lpar;
|
||||
BRep_Tool::Range(FirstEdge, fpar, lpar);
|
||||
BB.Range(FirstNewEdge, fpar, lpar);
|
||||
BRepAdaptor_Curve BAcurve(FirstNewEdge);
|
||||
gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
|
||||
if (CurNewVertex.IsNull())
|
||||
CurNewVertex = BRepLib_MakeVertex(FirstPnt);
|
||||
BB.Add(FirstNewEdge, CurNewVertex);
|
||||
BB.Add(FirstNewEdge, CurNewVertex.Oriented(TopAbs_REVERSED));
|
||||
myVertexNewVertex.Bind(CurVertex, CurNewVertex);
|
||||
}
|
||||
}
|
||||
for (; wexp.More(); wexp.Next())
|
||||
{
|
||||
CurEdge = wexp.Current();
|
||||
if (myOrientedEdgeNewEdge.IsBound(CurEdge))
|
||||
CurNewEdge = TopoDS::Edge(myOrientedEdgeNewEdge(CurEdge));
|
||||
else if (myEdgeNewEdge.IsBound(CurEdge))
|
||||
CurNewEdge = TopoDS::Edge(myEdgeNewEdge(CurEdge));
|
||||
else
|
||||
CurNewEdge = CurEdge;
|
||||
CurVertex = wexp.CurrentVertex();
|
||||
UpdateEdgesAndVertex(PrevEdge, PrevNewEdge,
|
||||
CurEdge, CurNewEdge,
|
||||
CurVertex);
|
||||
if (!PrevEdge.IsSame(PrevNewEdge) &&
|
||||
PrevEdge.Orientation() == TopAbs_REVERSED)
|
||||
PrevNewEdge.Reverse();
|
||||
BB.Add(aNewWire, PrevNewEdge);
|
||||
|
||||
PrevEdge = CurEdge;
|
||||
PrevNewEdge = CurNewEdge;
|
||||
}
|
||||
CurEdge = FirstEdge;
|
||||
CurNewEdge = FirstNewEdge;
|
||||
CurVertex = wexp.CurrentVertex();
|
||||
UpdateEdgesAndVertex(PrevEdge, PrevNewEdge,
|
||||
CurEdge, CurNewEdge,
|
||||
CurVertex);
|
||||
if (!PrevEdge.IsSame(PrevNewEdge) &&
|
||||
PrevEdge.Orientation() == TopAbs_REVERSED)
|
||||
PrevNewEdge.Reverse();
|
||||
BB.Add(aNewWire, PrevNewEdge);
|
||||
|
||||
aNewWire.Orientation(aWireOr);
|
||||
BB.Add(aBoundedNewFace, aNewWire);
|
||||
} //for (; itf.More(); itf.Next()) (iterator on face)
|
||||
}
|
||||
|
||||
//Assemble resulting shape
|
||||
TopoDS_Solid aSolid;
|
||||
BB.MakeSolid(aSolid);
|
||||
TopoDS_Shell aShell;
|
||||
BB.MakeShell(aShell);
|
||||
TopExp_Explorer Explo(myInitialShape, TopAbs_FACE);
|
||||
for (; Explo.More(); Explo.Next())
|
||||
{
|
||||
const TopoDS_Shape& aFace = Explo.Current();
|
||||
TopoDS_Shape aBoundedNewFace;
|
||||
if (myFaceNewFace.Contains(aFace))
|
||||
{
|
||||
const TopoDS_Shape& aNewFace = myFaceNewFace.FindFromKey(aFace);
|
||||
aBoundedNewFace = myNewFaceBoundedFace(aNewFace);
|
||||
if (aFace.Orientation() == TopAbs_REVERSED)
|
||||
aBoundedNewFace.Reverse();
|
||||
}
|
||||
else
|
||||
aBoundedNewFace = aFace;
|
||||
BB.Add(aShell, aBoundedNewFace);
|
||||
}
|
||||
BB.Add(aSolid, aShell);
|
||||
|
||||
ShapeFix_Shape Fixer(aSolid);
|
||||
Fixer.Perform();
|
||||
|
||||
myShape = Fixer.Shape();
|
||||
//myShape = aSolid;
|
||||
|
||||
Done();
|
||||
}
|
||||
|
||||
void BRepOffsetAPI_PatchFaces::UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEdge,
|
||||
TopoDS_Edge& thePrevNewEdge,
|
||||
const TopoDS_Edge& theCurEdge,
|
||||
TopoDS_Edge& theCurNewEdge,
|
||||
TopoDS_Vertex& theCurVertex)
|
||||
{
|
||||
BRep_Builder BB;
|
||||
|
||||
TopoDS_Vertex CurNewVertex;
|
||||
if (myVertexNewVertex.IsBound(theCurVertex))
|
||||
CurNewVertex = TopoDS::Vertex(myVertexNewVertex(theCurVertex));
|
||||
else
|
||||
{
|
||||
Standard_Boolean IsConstVertex = (!(myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge)) ||
|
||||
!(myEdgeNewEdge.IsBound(theCurEdge) || myOrientedEdgeNewEdge.IsBound(theCurEdge)));
|
||||
if (IsConstVertex)
|
||||
CurNewVertex = theCurVertex;
|
||||
}
|
||||
|
||||
Standard_Boolean IsSeamPrev = (myOrientedEdgeNewEdge.IsBound(thePrevEdge));
|
||||
Standard_Boolean IsSeamCur = (myOrientedEdgeNewEdge.IsBound(theCurEdge));
|
||||
|
||||
if ((myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge)) &&
|
||||
(myEdgeNewEdge.IsBound(theCurEdge) || myOrientedEdgeNewEdge.IsBound(theCurEdge))) //two new edges: intersect
|
||||
{
|
||||
Standard_Real ParamOnPrev, ParamOnCur, TolProj;
|
||||
gp_Pnt PntOnPrev, PntOnCur;
|
||||
ProjectVertexOnNewEdge(theCurVertex, thePrevEdge, thePrevNewEdge,
|
||||
ParamOnPrev, PntOnPrev, TolProj);
|
||||
ProjectVertexOnNewEdge(theCurVertex, theCurEdge, theCurNewEdge,
|
||||
ParamOnCur, PntOnCur, TolProj);
|
||||
|
||||
Standard_Real TolReached;
|
||||
gp_Pnt PntVtx = (CurNewVertex.IsNull())?
|
||||
BRep_Tool::Pnt(theCurVertex) : BRep_Tool::Pnt(CurNewVertex);
|
||||
TolReached = PntOnPrev.Distance(PntOnCur);
|
||||
Standard_Real DistVtoPrev = PntVtx.Distance(PntOnPrev);
|
||||
Standard_Real DistVtoCur = PntVtx.Distance(PntOnCur);
|
||||
TolReached = Max(TolReached, DistVtoPrev);
|
||||
TolReached = Max(TolReached, DistVtoCur);
|
||||
|
||||
BRepExtrema_ExtCC ExtrEE(thePrevNewEdge, theCurNewEdge);
|
||||
if (!ExtrEE.IsDone() || ExtrEE.NbExt() == 0)
|
||||
{
|
||||
cout<<endl<<"Extrema EE is not done"<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Standard_Integer imin = 1;
|
||||
for (Standard_Integer iext = 2; iext <= ExtrEE.NbExt(); iext++)
|
||||
if (ExtrEE.SquareDistance(iext) < ExtrEE.SquareDistance(imin))
|
||||
imin = iext;
|
||||
Standard_Real TolEE = sqrt(ExtrEE.SquareDistance(imin));
|
||||
gp_Pnt PntOnE1 = ExtrEE.PointOnE1(imin);
|
||||
gp_Pnt PntOnE2 = ExtrEE.PointOnE2(imin);
|
||||
Standard_Real DistVtoE1 = PntVtx.Distance(PntOnE1);
|
||||
Standard_Real DistVtoE2 = PntVtx.Distance(PntOnE2);
|
||||
TolEE = Max(TolEE, DistVtoE1);
|
||||
TolEE = Max(TolEE, DistVtoE2);
|
||||
if (TolEE < TolReached)
|
||||
{
|
||||
TolReached = TolEE;
|
||||
PntOnPrev = PntOnE1;
|
||||
PntOnCur = PntOnE2;
|
||||
ParamOnPrev = ExtrEE.ParameterOnE1(imin);
|
||||
ParamOnCur = ExtrEE.ParameterOnE2(imin);
|
||||
}
|
||||
}
|
||||
if (CurNewVertex.IsNull())
|
||||
{
|
||||
gp_Pnt NewPnt((PntOnPrev.XYZ() + PntOnCur.XYZ())/2);
|
||||
CurNewVertex = BRepLib_MakeVertex(NewPnt);
|
||||
myVertexNewVertex.Bind(theCurVertex, CurNewVertex);
|
||||
}
|
||||
BB.UpdateVertex(CurNewVertex, TolReached);
|
||||
if (!EdgeContains(thePrevNewEdge, CurNewVertex))
|
||||
{
|
||||
if (IsSeamCur)
|
||||
ParamOnPrev = RealLast();
|
||||
PutVertexToEdge(CurNewVertex, theCurVertex, thePrevNewEdge, thePrevEdge, ParamOnPrev);
|
||||
}
|
||||
|
||||
if (!EdgeContains(theCurNewEdge, CurNewVertex))
|
||||
{
|
||||
if (IsSeamPrev)
|
||||
ParamOnCur = RealLast();
|
||||
PutVertexToEdge(CurNewVertex, theCurVertex, theCurNewEdge, theCurEdge, ParamOnCur);
|
||||
}
|
||||
} //two new edges: intersect
|
||||
else if ((myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge)) ||
|
||||
(myEdgeNewEdge.IsBound(theCurEdge) || myOrientedEdgeNewEdge.IsBound(theCurEdge))) //one constant edge: project point onto curve
|
||||
{
|
||||
TopoDS_Edge ConstantEdge, ModifiedEdge, NewEdge;
|
||||
Standard_Boolean IsAdjacentSeam;
|
||||
if (myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge))
|
||||
{
|
||||
ConstantEdge = theCurEdge;
|
||||
ModifiedEdge = thePrevEdge;
|
||||
NewEdge = thePrevNewEdge;
|
||||
IsAdjacentSeam = IsSeamCur;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConstantEdge = thePrevEdge;
|
||||
ModifiedEdge = theCurEdge;
|
||||
NewEdge = theCurNewEdge;
|
||||
IsAdjacentSeam = IsSeamPrev;
|
||||
}
|
||||
|
||||
Standard_Real ParamOnNewEdge, TolReached;
|
||||
gp_Pnt PntOnNewEdge;
|
||||
ProjectVertexOnNewEdge(theCurVertex, ModifiedEdge, NewEdge,
|
||||
ParamOnNewEdge, PntOnNewEdge, TolReached);
|
||||
BB.UpdateVertex(theCurVertex, TolReached);
|
||||
|
||||
if (!EdgeContains(NewEdge, theCurVertex))
|
||||
PutVertexToEdge(theCurVertex, theCurVertex, NewEdge, ModifiedEdge, ParamOnNewEdge);
|
||||
} //else (one constant edge: project point onto curve)
|
||||
else //two constant edges
|
||||
{
|
||||
//nothing ?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BRepOffsetAPI_PatchFaces::PutVertexToEdge(const TopoDS_Vertex& theVertex,
|
||||
const TopoDS_Vertex& theProVertex,
|
||||
TopoDS_Edge& theEdge,
|
||||
const TopoDS_Edge& theProEdge,
|
||||
const Standard_Real theParamOnEdge)
|
||||
{
|
||||
BRep_Builder BB;
|
||||
|
||||
TopAbs_Orientation anOr = OrientationInEdge(theProVertex, theProEdge);
|
||||
if (myEdgeNewEdge.IsBound(theProEdge) &&
|
||||
myEdgeNewEdge(theProEdge).Orientation() == TopAbs_REVERSED)
|
||||
anOr = TopAbs::Reverse(anOr);
|
||||
|
||||
TopoDS_Shape F_Edge = theEdge.Oriented(TopAbs_FORWARD);
|
||||
F_Edge.Free(Standard_True);
|
||||
BB.Add(F_Edge, theVertex.Oriented(anOr));
|
||||
if (!Precision::IsInfinite(theParamOnEdge))
|
||||
{
|
||||
Standard_Real fpar, lpar;
|
||||
BRep_Tool::Range(theEdge, fpar, lpar);
|
||||
if (anOr == TopAbs_FORWARD)
|
||||
BB.Range(theEdge, theParamOnEdge, lpar);
|
||||
else
|
||||
BB.Range(theEdge, fpar, theParamOnEdge);
|
||||
}
|
||||
}
|
99
src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx
Normal file
99
src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx
Normal file
@@ -0,0 +1,99 @@
|
||||
// Created on: 2012-08-06
|
||||
// Created by: jgv@ROLEX
|
||||
// Copyright (c) 2012-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.
|
||||
|
||||
#ifndef _BRepOffsetAPI_PatchFaces_HeaderFile
|
||||
#define _BRepOffsetAPI_PatchFaces_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_DefineAlloc.hxx>
|
||||
#include <Standard_Handle.hxx>
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||
#include <TopTools_DataMapOfOrientedShapeShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <BRepBuilderAPI_MakeShape.hxx>
|
||||
class TopoDS_Shape;
|
||||
|
||||
|
||||
//! Describes functions to replace some faces in a shape
|
||||
//! by patches
|
||||
class BRepOffsetAPI_PatchFaces : public BRepBuilderAPI_MakeShape
|
||||
{
|
||||
public:
|
||||
|
||||
DEFINE_STANDARD_ALLOC
|
||||
|
||||
|
||||
//! General constructor.
|
||||
Standard_EXPORT BRepOffsetAPI_PatchFaces(const TopoDS_Shape& aShape);
|
||||
|
||||
//! Adds the patch face for the face in the shape.
|
||||
Standard_EXPORT void AddPatchFace (const TopoDS_Face& theFace, const TopoDS_Face& thePatchFace);
|
||||
|
||||
Standard_EXPORT virtual void Build() Standard_OVERRIDE;
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Standard_EXPORT void UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEdge,
|
||||
TopoDS_Edge& thePrevNewEdge,
|
||||
const TopoDS_Edge& theCurEdge,
|
||||
TopoDS_Edge& theCurNewEdge,
|
||||
TopoDS_Vertex& theCurVertex);
|
||||
|
||||
Standard_EXPORT void PutVertexToEdge(const TopoDS_Vertex& theVertex,
|
||||
const TopoDS_Vertex& theProVertex,
|
||||
TopoDS_Edge& theEdge,
|
||||
const TopoDS_Edge& theProEdge,
|
||||
const Standard_Real theParamOnEdge);
|
||||
|
||||
|
||||
TopoDS_Shape myInitialShape;
|
||||
|
||||
TopTools_IndexedDataMapOfShapeShape myFacePatchFace;
|
||||
TopTools_IndexedDataMapOfShapeShape myFaceNewFace;
|
||||
TopTools_DataMapOfShapeShape myNewFaceBoundedFace;
|
||||
TopTools_DataMapOfShapeShape myEdgeNewEdge;
|
||||
TopTools_DataMapOfOrientedShapeShape myOrientedEdgeNewEdge;
|
||||
TopTools_DataMapOfShapeShape myVertexNewVertex;
|
||||
TopTools_MapOfShape myTangentEdges;
|
||||
|
||||
TopTools_IndexedDataMapOfShapeListOfShape myEFmap;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _BRepOffsetAPI_PatchFaces_HeaderFile
|
@@ -27,3 +27,5 @@ BRepOffsetAPI_SequenceOfSequenceOfShape.hxx
|
||||
BRepOffsetAPI_Sewing.hxx
|
||||
BRepOffsetAPI_ThruSections.cxx
|
||||
BRepOffsetAPI_ThruSections.hxx
|
||||
BRepOffsetAPI_PatchFaces.cxx
|
||||
BRepOffsetAPI_PatchFaces.hxx
|
||||
|
@@ -54,6 +54,8 @@
|
||||
#include <LocOpe_FindEdges.hxx>
|
||||
#include <LocOpe_FindEdgesInFace.hxx>
|
||||
|
||||
#include <BRepOffsetAPI_PatchFaces.hxx>
|
||||
|
||||
#include <BRepOffsetAPI_MakeOffsetShape.hxx>
|
||||
#include <BRepOffsetAPI_MakeThickSolid.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
@@ -2249,6 +2251,35 @@ static Standard_Integer BOSS(Draw_Interpretor& theCommands,
|
||||
return 1;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : patchfaces
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
static Standard_Integer patchfaces(Draw_Interpretor& /*di*/,
|
||||
Standard_Integer n, const char** a)
|
||||
{
|
||||
if (n < 5) return 1;
|
||||
|
||||
TopoDS_Shape aShape = DBRep::Get(a[2]);
|
||||
if (aShape.IsNull()) return 1;
|
||||
|
||||
TopoDS_Shape aLocalFace = DBRep::Get(a[3], TopAbs_FACE);
|
||||
if (aLocalFace.IsNull()) return 1;
|
||||
TopoDS_Face aFace = TopoDS::Face(aLocalFace);
|
||||
|
||||
TopoDS_Shape aLocalNewFace = DBRep::Get(a[4], TopAbs_FACE);
|
||||
if (aLocalNewFace.IsNull()) return 1;
|
||||
TopoDS_Face aNewFace = TopoDS::Face(aLocalNewFace);
|
||||
|
||||
BRepOffsetAPI_PatchFaces Builder(aShape);
|
||||
Builder.AddPatchFace(aFace, aNewFace);
|
||||
Builder.Build();
|
||||
|
||||
TopoDS_Shape Result = Builder.Shape();
|
||||
DBRep::Set(a[1], Result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FeatureCommands
|
||||
@@ -2395,4 +2426,6 @@ void BRepTest::FeatureCommands (Draw_Interpretor& theCommands)
|
||||
" Perform fillet on top and bottom edges of dprism :bossage dprism result radtop radbottom First/LastShape (1/2)",
|
||||
__FILE__,BOSS);
|
||||
|
||||
theCommands.Add("patchfaces", "patchfaces res shape face newface",
|
||||
__FILE__,patchfaces,g);
|
||||
}
|
||||
|
@@ -99,7 +99,55 @@ void TopExp::MapShapesAndAncestors
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MapShapesAndUniqueAncestors
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void TopExp::MapShapesAndUniqueAncestors
|
||||
(const TopoDS_Shape& S,
|
||||
const TopAbs_ShapeEnum TS,
|
||||
const TopAbs_ShapeEnum TA,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& M,
|
||||
const Standard_Boolean useOrientation)
|
||||
{
|
||||
TopTools_ListOfShape empty;
|
||||
|
||||
// visit ancestors
|
||||
TopExp_Explorer exa(S,TA);
|
||||
while (exa.More())
|
||||
{
|
||||
// visit shapes
|
||||
const TopoDS_Shape& anc = exa.Current();
|
||||
TopExp_Explorer exs(anc,TS);
|
||||
while (exs.More())
|
||||
{
|
||||
Standard_Integer index = M.FindIndex(exs.Current());
|
||||
if (index == 0)
|
||||
index = M.Add(exs.Current(),empty);
|
||||
TopTools_ListOfShape& aList = M(index);
|
||||
// check if anc already exists in a list
|
||||
TopTools_ListIteratorOfListOfShape it(aList);
|
||||
for (; it.More(); it.Next())
|
||||
if (useOrientation? anc.IsEqual(it.Value()) : anc.IsSame(it.Value()))
|
||||
break;
|
||||
if (!it.More())
|
||||
aList.Append(anc);
|
||||
exs.Next();
|
||||
}
|
||||
exa.Next();
|
||||
}
|
||||
|
||||
// visit shapes not under ancestors
|
||||
TopExp_Explorer ex(S,TS,TA);
|
||||
while (ex.More())
|
||||
{
|
||||
Standard_Integer index = M.FindIndex(ex.Current());
|
||||
if (index == 0)
|
||||
M.Add(ex.Current(),empty);
|
||||
ex.Next();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FirstVertex
|
||||
|
@@ -66,6 +66,18 @@ public:
|
||||
//! Warning: The map is not cleared at first.
|
||||
Standard_EXPORT static void MapShapesAndAncestors (const TopoDS_Shape& S, const TopAbs_ShapeEnum TS, const TopAbs_ShapeEnum TA, TopTools_IndexedDataMapOfShapeListOfShape& M);
|
||||
|
||||
//! Stores in the map <M> all the subshape of <S> of
|
||||
//! type <TS> for each one append to the list all
|
||||
//! unique ancestors of type <TA>. For example map all
|
||||
//! the edges and bind the list of faces.
|
||||
//! useOrientation = True : taking account the ancestor orientation
|
||||
//! Warning: The map is not cleared at first.
|
||||
Standard_EXPORT static void MapShapesAndUniqueAncestors (const TopoDS_Shape& S,
|
||||
const TopAbs_ShapeEnum TS,
|
||||
const TopAbs_ShapeEnum TA,
|
||||
TopTools_IndexedDataMapOfShapeListOfShape& M,
|
||||
const Standard_Boolean useOrientation = Standard_False);
|
||||
|
||||
//! Returns the Vertex of orientation FORWARD in E. If
|
||||
//! there is none returns a Null Shape.
|
||||
//! CumOri = True : taking account the edge orientation
|
||||
|
23
tests/patchfaces/begin
Normal file
23
tests/patchfaces/begin
Normal file
@@ -0,0 +1,23 @@
|
||||
# To prevent loops limit to 10 minutes
|
||||
cpulimit 100
|
||||
if { [array get Draw_Groups "TOPOLOGY Feature commands"] == "" } {
|
||||
pload TOPTEST
|
||||
}
|
||||
if { [array get Draw_Groups "Shape Healing"] == "" } {
|
||||
pload XSDRAW
|
||||
}
|
||||
if { [info exists imagedir] == 0 } {
|
||||
set imagedir .
|
||||
}
|
||||
if { [info exists test_image ] == 0 } {
|
||||
set test_image photo
|
||||
}
|
||||
proc PATCHFACES {i} {
|
||||
uplevel #0 binrestore [locate_data_file shape_3_$i.bin] s
|
||||
uplevel #0 tclean s
|
||||
uplevel #0 removeloc s s
|
||||
uplevel #0 explode s
|
||||
uplevel #0 tcopy s_1 InitShape
|
||||
|
||||
uplevel #0 patchfaces result s_1 s_2 s_3
|
||||
}
|
1
tests/patchfaces/end
Normal file
1
tests/patchfaces/end
Normal file
@@ -0,0 +1 @@
|
||||
puts "TEST COMPLETED"
|
1
tests/patchfaces/grids.list
Normal file
1
tests/patchfaces/grids.list
Normal file
@@ -0,0 +1 @@
|
||||
001 replace
|
2
tests/patchfaces/parse.rules
Normal file
2
tests/patchfaces/parse.rules
Normal file
@@ -0,0 +1,2 @@
|
||||
FAILED /\bFaulty\b/ bad shape
|
||||
OK /Relative error of mass computation/ message from vprops
|
2
tests/patchfaces/replace/end
Normal file
2
tests/patchfaces/replace/end
Normal file
@@ -0,0 +1,2 @@
|
||||
checkshape result
|
||||
checkview -display result -2d -path ${imagedir}/${test_image}.png
|
1
tests/patchfaces/replace/test_1
Normal file
1
tests/patchfaces/replace/test_1
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 1
|
1
tests/patchfaces/replace/test_10
Normal file
1
tests/patchfaces/replace/test_10
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 10
|
1
tests/patchfaces/replace/test_11
Normal file
1
tests/patchfaces/replace/test_11
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 11
|
1
tests/patchfaces/replace/test_12
Normal file
1
tests/patchfaces/replace/test_12
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 12
|
1
tests/patchfaces/replace/test_13
Normal file
1
tests/patchfaces/replace/test_13
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 13
|
1
tests/patchfaces/replace/test_14
Normal file
1
tests/patchfaces/replace/test_14
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 14
|
1
tests/patchfaces/replace/test_15
Normal file
1
tests/patchfaces/replace/test_15
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 15
|
1
tests/patchfaces/replace/test_16
Normal file
1
tests/patchfaces/replace/test_16
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 16
|
1
tests/patchfaces/replace/test_17
Normal file
1
tests/patchfaces/replace/test_17
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 17
|
1
tests/patchfaces/replace/test_18
Normal file
1
tests/patchfaces/replace/test_18
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 18
|
1
tests/patchfaces/replace/test_19
Normal file
1
tests/patchfaces/replace/test_19
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 19
|
1
tests/patchfaces/replace/test_2
Normal file
1
tests/patchfaces/replace/test_2
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 2
|
1
tests/patchfaces/replace/test_20
Normal file
1
tests/patchfaces/replace/test_20
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 20
|
1
tests/patchfaces/replace/test_21
Normal file
1
tests/patchfaces/replace/test_21
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 21
|
1
tests/patchfaces/replace/test_22
Normal file
1
tests/patchfaces/replace/test_22
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 22
|
1
tests/patchfaces/replace/test_23
Normal file
1
tests/patchfaces/replace/test_23
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 23
|
1
tests/patchfaces/replace/test_24
Normal file
1
tests/patchfaces/replace/test_24
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 24
|
1
tests/patchfaces/replace/test_25
Normal file
1
tests/patchfaces/replace/test_25
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 25
|
1
tests/patchfaces/replace/test_26
Normal file
1
tests/patchfaces/replace/test_26
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 26
|
1
tests/patchfaces/replace/test_27
Normal file
1
tests/patchfaces/replace/test_27
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 27
|
1
tests/patchfaces/replace/test_28
Normal file
1
tests/patchfaces/replace/test_28
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 28
|
1
tests/patchfaces/replace/test_29
Normal file
1
tests/patchfaces/replace/test_29
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 29
|
1
tests/patchfaces/replace/test_3
Normal file
1
tests/patchfaces/replace/test_3
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 3
|
1
tests/patchfaces/replace/test_30
Normal file
1
tests/patchfaces/replace/test_30
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 30
|
1
tests/patchfaces/replace/test_31
Normal file
1
tests/patchfaces/replace/test_31
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 31
|
1
tests/patchfaces/replace/test_32
Normal file
1
tests/patchfaces/replace/test_32
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 32
|
1
tests/patchfaces/replace/test_33
Normal file
1
tests/patchfaces/replace/test_33
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 33
|
1
tests/patchfaces/replace/test_34
Normal file
1
tests/patchfaces/replace/test_34
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 34
|
1
tests/patchfaces/replace/test_35
Normal file
1
tests/patchfaces/replace/test_35
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 35
|
1
tests/patchfaces/replace/test_4
Normal file
1
tests/patchfaces/replace/test_4
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 4
|
1
tests/patchfaces/replace/test_5
Normal file
1
tests/patchfaces/replace/test_5
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 5
|
1
tests/patchfaces/replace/test_6
Normal file
1
tests/patchfaces/replace/test_6
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 6
|
1
tests/patchfaces/replace/test_7
Normal file
1
tests/patchfaces/replace/test_7
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 7
|
1
tests/patchfaces/replace/test_8
Normal file
1
tests/patchfaces/replace/test_8
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 8
|
1
tests/patchfaces/replace/test_9
Normal file
1
tests/patchfaces/replace/test_9
Normal file
@@ -0,0 +1 @@
|
||||
PATCHFACES 9
|
Reference in New Issue
Block a user