1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/BOPTools/BOPTools_AlgoTools_2.cxx
Benjamin Bihler 012264339e 0029765: BOPTools_AlgoTools::MakeSplitEdge Creates Illegal Edge
Method MakeSplitEdge checks arguments order.
This makes the method more generic.
Taking vertex orientation into account.
2018-06-14 14:03:01 +03:00

540 lines
15 KiB
C++

// Created by: Peter KURNEV
// 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 <BOPTools_AlgoTools.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <Geom_Curve.hxx>
#include <GeomAbs_CurveType.hxx>
#include <gp_Pnt.hxx>
#include <IntTools_Context.hxx>
#include <IntTools_Curve.hxx>
#include <IntTools_Range.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
static
void TreatCompound(const TopoDS_Shape& theC1,
TopTools_ListOfShape& theLSX);
//=======================================================================
// function: UpdateVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::UpdateVertex
(const TopoDS_Vertex& aVF,
const TopoDS_Vertex& aNewVertex)
{
Standard_Real aTolVF, aTolNewVertex, aDist, aDTol=1.e-12, aNewTol;
//
gp_Pnt aPVF=BRep_Tool::Pnt(aVF);
gp_Pnt aPNewVertex=BRep_Tool::Pnt(aNewVertex);
aTolVF=BRep_Tool::Tolerance(aVF);
aTolNewVertex=BRep_Tool::Tolerance(aNewVertex);
aDist=aPVF.Distance(aPNewVertex);
aNewTol=aDist+aTolNewVertex;
if (aNewTol>aTolVF) {
BRep_Builder BB;
BB.UpdateVertex (aVF, aNewTol+aDTol);
}
}
//=======================================================================
// function: UpdateVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::UpdateVertex (const TopoDS_Edge& aE,
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
Standard_Real aTolV, aDist, aDTol=1.e-12, aFirst, aLast;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
GeomAdaptor_Curve aCA( BRep_Tool::Curve(aE, aFirst, aLast) );
aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist+aDTol);
}
}
//
//=======================================================================
// function: UpdateVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::UpdateVertex (const IntTools_Curve& aC,
const Standard_Real aT,
const TopoDS_Vertex& aV)
{
Standard_Real aTolV, aDist, aDTol=1.e-12;
gp_Pnt aPc;
gp_Pnt aPv=BRep_Tool::Pnt(aV);
aTolV=BRep_Tool::Tolerance(aV);
GeomAdaptor_Curve aCA( aC.Curve() );
aCA.D0(aT, aPc);
aDist=aPv.Distance(aPc);
if (aDist>aTolV) {
BRep_Builder BB;
BB.UpdateVertex (aV, aDist+aDTol);
}
}
//=======================================================================
// function: MakeSectEdge
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeSectEdge(const IntTools_Curve& aIC,
const TopoDS_Vertex& aV1,
const Standard_Real aP1,
const TopoDS_Vertex& aV2,
const Standard_Real aP2,
TopoDS_Edge& aNewEdge)
{
Handle(Geom_Curve) aC=aIC.Curve ();
BRepBuilderAPI_MakeEdge aMakeEdge(aC, aV1, aV2, aP1, aP2);
const TopoDS_Edge& aE=TopoDS::Edge(aMakeEdge.Shape());
//
// Range must be as it was !
BRep_Builder aBB;
aBB.Range (aE, aP1, aP2);
//
aNewEdge=aE;
}
//=======================================================================
// function: CopyEdge
// purpose:
//=======================================================================
TopoDS_Edge BOPTools_AlgoTools::CopyEdge(const TopoDS_Edge& theEdge)
{
TopoDS_Edge aNewEdge = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD));
aNewEdge.EmptyCopy();
for (TopoDS_Iterator it(theEdge, Standard_False); it.More(); it.Next())
BRep_Builder().Add(aNewEdge, it.Value());
aNewEdge.Orientation(theEdge.Orientation());
return aNewEdge;
}
//=======================================================================
// function: MakeSplitEdge
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeSplitEdge(const TopoDS_Edge& aE,
const TopoDS_Vertex& aV1,
const Standard_Real aP1,
const TopoDS_Vertex& aV2,
const Standard_Real aP2,
TopoDS_Edge& aNewEdge)
{
TopoDS_Edge E = TopoDS::Edge(aE.Oriented(TopAbs_FORWARD));
E.EmptyCopy();
//
BRep_Builder BB;
if (!aV1.IsNull()) {
if (aP1 < aP2) {
BB.Add (E, TopoDS::Vertex(aV1.Oriented(TopAbs_FORWARD)));
}
else {
BB.Add (E, TopoDS::Vertex(aV1.Oriented(TopAbs_REVERSED)));
}
}
if (!aV2.IsNull()) {
if (aP1 < aP2) {
BB.Add (E, TopoDS::Vertex(aV2.Oriented(TopAbs_REVERSED)));
}
else {
BB.Add (E, TopoDS::Vertex(aV2.Oriented(TopAbs_FORWARD)));
}
}
if (aP1 < aP2) {
BB.Range(E, aP1, aP2);
}
else {
BB.Range(E, aP2, aP1);
}
aNewEdge=E;
aNewEdge.Orientation(aE.Orientation());
}
//=======================================================================
// function: MakeNewVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Vertex& aV1,
const TopoDS_Vertex& aV2,
TopoDS_Vertex& aNewVertex)
{
gp_Pnt aPnt1=BRep_Tool::Pnt(aV1);
Standard_Real aTol1=BRep_Tool::Tolerance(aV1);
gp_Pnt aPnt2=BRep_Tool::Pnt(aV2);
Standard_Real aTol2=BRep_Tool::Tolerance(aV2);
Standard_Real aMaxTol, aDist;
aDist=aPnt1.Distance(aPnt2);
aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
aMaxTol=aMaxTol+0.5*aDist;
const gp_XYZ& aXYZ1=aPnt1.XYZ();
const gp_XYZ& aXYZ2=aPnt2.XYZ();
gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
gp_Pnt aNewPnt(aNewXYZ);
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
}
//=======================================================================
// function: MakeNewVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeNewVertex(const gp_Pnt& aP,
const Standard_Real aTol,
TopoDS_Vertex& aNewVertex)
{
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aP, aTol);
}
//=======================================================================
// function: MakeNewVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
const Standard_Real aParm1,
const TopoDS_Edge& aE2,
const Standard_Real aParm2,
TopoDS_Vertex& aNewVertex)
{
Standard_Real aTol1, aTol2, aMaxTol, aDist;
gp_Pnt aPnt1, aPnt2;
PointOnEdge (aE1, aParm1, aPnt1);
PointOnEdge (aE2, aParm2, aPnt2);
aTol1=BRep_Tool::Tolerance(aE1);
aTol2=BRep_Tool::Tolerance(aE2);
aDist=aPnt1.Distance(aPnt2);
aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
aMaxTol=aMaxTol+0.5*aDist;
const gp_XYZ& aXYZ1=aPnt1.XYZ();
const gp_XYZ& aXYZ2=aPnt2.XYZ();
gp_XYZ aNewXYZ=0.5*(aXYZ1+aXYZ2);
gp_Pnt aNewPnt(aNewXYZ);
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aNewPnt, aMaxTol);
}
//=======================================================================
// function: MakeNewVertex
// purpose:
//=======================================================================
void BOPTools_AlgoTools::MakeNewVertex(const TopoDS_Edge& aE1,
const Standard_Real aParm1,
const TopoDS_Face& aF1,
TopoDS_Vertex& aNewVertex)
{
Standard_Real aTol1, aTol2, aMaxTol, delta=1.e-12;
gp_Pnt aPnt;
PointOnEdge (aE1, aParm1, aPnt);
aTol1=BRep_Tool::Tolerance(aE1);
aTol2=BRep_Tool::Tolerance(aF1);
//
//aMaxTol=(aTol1>aTol2)? aTol1 : aTol2;
aMaxTol=aTol1+aTol2+delta;
//
BRep_Builder aBB;
aBB.MakeVertex (aNewVertex, aPnt, aMaxTol);
}
//=======================================================================
// function: PointOnEdge
// purpose:
//=======================================================================
void BOPTools_AlgoTools::PointOnEdge(const TopoDS_Edge& aE,
const Standard_Real aParm,
gp_Pnt& aPnt)
{
Standard_Real f, l;
Handle(Geom_Curve) C1=BRep_Tool::Curve(aE, f, l);
C1->D0(aParm, aPnt);
}
//=======================================================================
//function : CorrectRange
//purpose :
//=======================================================================
void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE1,
const TopoDS_Edge& aE2,
const IntTools_Range& aSR,
IntTools_Range& aNewSR)
{
Standard_Integer i;
Standard_Real aRes, aTolE1, aTolE2, aTF, aTL, dT;
BRepAdaptor_Curve aBC;
GeomAbs_CurveType aCT;
gp_Pnt aP;
gp_Vec aDer;
//
aNewSR=aSR;
//
aBC.Initialize(aE1);
aCT=aBC.GetType();
if (aCT==GeomAbs_Line) {
return;
}
//
dT=Precision::PConfusion();
aTF=aSR.First();
aTL=aSR.Last();
//
aTolE1=BRep_Tool::Tolerance(aE1);
aTolE2=BRep_Tool::Tolerance(aE2);
//
for(i=0; i<2; ++i) {
aRes = 2.*(aTolE1 + aTolE2);
//
if (aCT==GeomAbs_BezierCurve ||
aCT==GeomAbs_BSplineCurve||
aCT==GeomAbs_OffsetCurve ||
aCT==GeomAbs_OtherCurve) {
if(!i){
aBC.D1 (aTF, aP, aDer);
}
else {
aBC.D1 (aTL, aP, aDer);
}
//
Standard_Real aMgn = aDer.Magnitude();
if(aMgn > 1.e-12) {
aRes = aRes/aMgn ;
}
else {
aRes = aBC.Resolution(aRes);
}
} // if (aCT==GeomAbs_BezierCurve||...
else {
aRes = aBC.Resolution(aRes);
}
//
if(!i) {
aNewSR.SetFirst (aTF+aRes);
}
else {
aNewSR.SetLast (aTL-aRes);
}
//
if ((aNewSR.Last()-aNewSR.First()) < dT) {
aNewSR=aSR;
}
//aNewSR=((aNewSR.Last()-aNewSR.First()) < dT) ? aSR : aNewSR;
}
}
//=======================================================================
//function : CorrectRange
//purpose :
//=======================================================================
void BOPTools_AlgoTools::CorrectRange(const TopoDS_Edge& aE,
const TopoDS_Face& aF,
const IntTools_Range& aSR,
IntTools_Range& aNewSR)
{
Standard_Integer i;
Standard_Real aRes, aTolF, aTF, aTL, dT;
BRepAdaptor_Curve aBC;
GeomAbs_CurveType aCT;
gp_Pnt aP;
gp_Vec aDer;
//
aNewSR=aSR;
//
dT=Precision::PConfusion();
aTF=aSR.First();
aTL=aSR.Last();
//
aBC.Initialize(aE);
aCT=aBC.GetType();
//
aTolF=BRep_Tool::Tolerance(aF);
//
for(i=0; i<2; ++i) {
aRes =aTolF;
if (aCT==GeomAbs_BezierCurve ||
aCT==GeomAbs_BSplineCurve||
aCT==GeomAbs_OffsetCurve ||
aCT==GeomAbs_OtherCurve) {
if(!i){
aBC.D1 (aTF, aP, aDer);
}
else {
aBC.D1 (aTL, aP, aDer);
}
//
Standard_Real aMgn = aDer.Magnitude();
if(aMgn > 1.e-12) {
aRes = aRes/aMgn ;
}
else {
aRes = aBC.Resolution(aRes);
}
} // if (aCT==GeomAbs_BezierCurve||...
else {
aRes = aBC.Resolution(aRes);
}
//
if(!i) {
aNewSR.SetFirst (aTF+aRes);
}
else {
aNewSR.SetLast (aTL-aRes);
}
//
if ((aNewSR.Last()-aNewSR.First()) < dT) {
aNewSR=aSR;
}
}
}
//=======================================================================
//function : Dimension
//purpose :
//=======================================================================
Standard_Integer BOPTools_AlgoTools::Dimension(const TopoDS_Shape& theS)
{
Standard_Integer i, iRet, iRx0 = 0, iRx = 0;
TopAbs_ShapeEnum aTS;
TopTools_ListOfShape aLS;
TopTools_ListIteratorOfListOfShape aIt;
//
aTS=theS.ShapeType();
if (aTS!=TopAbs_COMPOUND) {
switch (aTS) {
case TopAbs_EDGE:
case TopAbs_WIRE:
iRet=1;
break;
case TopAbs_FACE:
case TopAbs_SHELL:
iRet=2;
break;
case TopAbs_SOLID:
case TopAbs_COMPSOLID:
iRet=3;
break;
default:
iRet=0;
}
return iRet;
}
//
iRet=-1;
TreatCompound(theS, aLS);
if(aLS.IsEmpty()) {
iRet = -2; //empty compound
return iRet;
}
aIt.Initialize(aLS);
for (i=0; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSx=aIt.Value();
iRx=Dimension(aSx);
if (!i) {
iRx0=iRx;
i=1;
continue;
}
if (iRx!=iRx0) {
return iRet;// -1
}
}
return iRx;
}
//=======================================================================
//function : TreatCompound
//purpose :
//=======================================================================
void TreatCompound(const TopoDS_Shape& theC1,
TopTools_ListOfShape& theLSX)
{
Standard_Integer aNbC1;
TopAbs_ShapeEnum aType;
TopTools_ListOfShape aLC, aLC1;
TopTools_ListIteratorOfListOfShape aIt, aIt1;
TopoDS_Iterator aItC;
//
aLC.Append (theC1);
for(;;) {
aLC1.Clear();
aIt.Initialize(aLC);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aC=aIt.Value(); //C is compound
//
aItC.Initialize(aC);
for (; aItC.More(); aItC.Next()) {
const TopoDS_Shape& aS=aItC.Value();
aType=aS.ShapeType();
if (aType==TopAbs_COMPOUND) {
aLC1.Append(aS);
}
else {
theLSX.Append(aS);
}
}
}
//
aNbC1=aLC1.Extent();
if (!aNbC1) {
break;
}
//
aLC.Clear();
aIt.Initialize(aLC1);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSC=aIt.Value();
aLC.Append(aSC);
}
}// while(1)
}