1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

4 Commits

Author SHA1 Message Date
isn
c0cd8715bd 0028991: HLR: Building of the set faces on the base of HLR contours
1) Draft implementation of face builder on the base of HLR contours has been added
2) new method in bnd_box2d class: distance from 2d point to box
3) small re factoring of  some HLR classes
4) new QA command (OCC28991) for testing of new functionality
2017-08-14 14:36:14 +03:00
isn
96066092b6 Improving of accuracy of contour's building;
Eliminating of hanging in ComputeInternalPoints()
2017-08-11 20:11:00 +03:00
isn
dcbff09b8e get rid of recursive loop (HLRBRep_Data::NextEdge()) 2017-08-11 20:07:13 +03:00
isn
93b792e86b 0028873: Optimization of HLR
draft version. Parallelization of:
1) contour's building, 2) BRep-adaptor creation of original shapes, 3) BRep-adaptor creation of outlined shapes
Also, some code re-factoring/re-design to provide the thread-safety of Contap functions.
2017-08-11 20:02:33 +03:00
25 changed files with 1624 additions and 149 deletions

View File

@@ -292,7 +292,7 @@ void AIS_Shape::Compute(const Handle(Prs3d_Projector)& aProjector,
OCC_CATCH_SIGNALS
switch (TypeOfHLR()) {
case Prs3d_TOH_Algo:
StdPrs_HLRShape::Add (aPresentation, SH, myDrawer, aProjector);
StdPrs_HLRShape::Add (aPresentation, SH, myDrawer, aProjector);
break;
case Prs3d_TOH_PolyAlgo:
default:

View File

@@ -67,7 +67,7 @@ void BRepTopAdaptor_Tool::Init(const Handle(Adaptor3d_HSurface)& surface,
myloaded=Standard_True;
}
Handle(BRepTopAdaptor_TopolTool) BRepTopAdaptor_Tool::GetTopolTool() {
Handle(BRepTopAdaptor_TopolTool) BRepTopAdaptor_Tool::GetTopolTool() const{
if(myloaded) {
return(myTopolTool);
}
@@ -79,7 +79,7 @@ Handle(BRepTopAdaptor_TopolTool) BRepTopAdaptor_Tool::GetTopolTool() {
}
}
Handle(Adaptor3d_HSurface) BRepTopAdaptor_Tool::GetSurface() {
Handle(Adaptor3d_HSurface) BRepTopAdaptor_Tool::GetSurface() const{
if(myloaded) {
return(myHSurface);
}

View File

@@ -46,11 +46,11 @@ public:
Standard_EXPORT void Init (const Handle(Adaptor3d_HSurface)& Surface, const Standard_Real Tol2d);
Standard_EXPORT Handle(BRepTopAdaptor_TopolTool) GetTopolTool();
Standard_EXPORT Handle(BRepTopAdaptor_TopolTool) GetTopolTool() const;
Standard_EXPORT void SetTopolTool (const Handle(BRepTopAdaptor_TopolTool)& TT);
Standard_EXPORT Handle(Adaptor3d_HSurface) GetSurface();
Standard_EXPORT Handle(Adaptor3d_HSurface) GetSurface() const;
Standard_EXPORT void Destroy();
~BRepTopAdaptor_Tool()

View File

@@ -300,3 +300,23 @@ void Bnd_Box2d::Dump () const
cout << "\n Gap : " << Gap;
cout << "\n";
}
Standard_Real Bnd_Box2d::SquareDistance (const gp_Pnt2d& thePnt2d) const
{
Standard_Real Xmin, Xmax, Ymin, Ymax;
Standard_Real X = thePnt2d.X(), Y = thePnt2d.Y();
Standard_Real dd = 0;
Get(Xmin, Ymin, Xmax, Ymax);
if (X < Xmin)
dd += (Xmin - X)*(Xmin - X);
else if (X > Xmax)
dd += (Xmax - X)*(Xmax - X);
if (Y < Ymin)
dd += (Ymin - Y)*(Ymin - Y);
else if (Y > Ymax)
dd += (Ymax - Y)*(Ymax - Y);
return dd;
}

View File

@@ -183,6 +183,10 @@ public:
//! Returns True if the 2d pnt <P> is out <me>.
Standard_EXPORT Standard_Boolean IsOut (const gp_Pnt2d& P) const;
//! Returns distance from point <thePnt2d> to <me>
//! distance will be 0 if point is inside of <me>
Standard_EXPORT Standard_Real SquareDistance (const gp_Pnt2d& thePnt2d) const;
//! Returns True if <Box2d> is out <me>.
Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box2d& Other) const;

View File

@@ -36,14 +36,15 @@ void Contap_ArcFunction::Set(const Handle(Adaptor3d_HSurface)& S)
{
mySurf = S;
Standard_Integer i;
Standard_Integer nbs = Contap_HContTool::NbSamplePoints(S);
Standard_Real uinf, vinf, usup, vsup;
Standard_Integer nbs = Contap_HContTool::NbSamplePoints(S, uinf, vinf, usup, vsup);
Standard_Real U,V;
// gp_Vec d1u,d1v;
gp_Vec norm;
if (nbs > 0) {
myMean = 0.;
for (i = 1; i <= nbs; i++) {
Contap_HContTool::SamplePoint(S,i,U,V);
Contap_HContTool::SamplePoint(S,i,U,V, uinf, vinf, usup, vsup);
// Adaptor3d_HSurfaceTool::D1(S,U,V,solpt,d1u,d1v);
// myMean = myMean + d1u.Crossed(d1v).Magnitude();
Contap_SurfProps::Normale(S,U,V,solpt,norm);

View File

@@ -1237,9 +1237,16 @@ void ComputeInternalPoints
// Essayer de converger
// cout << "Changement de signe detecte" << endl;
solution = Standard_False;
while (!solution) {
X(1) = (XInf(1) + XSup(1)) /2.;
X(2) = (XInf(2) + XSup(2)) /2.;
math_Vector dir1(1,2), dir2(1,2);
math_Vector prevX(1,2), prevPrevX (1,2);
int count = 0;
int revCount = 0;
double dot = 0;
double t = 0.5;
while (!solution)
{
X(1) =/* (XInf(1) + XSup(1)) /2.;*/ XInf(1) + t * (XSup(1) - XInf(1));
X(2) = /*(XInf(2) + XSup(2)) /2.;*/XInf(2) + t * (XSup(2) - XInf(2));
rsnld.Perform(SFunc,X,infb,supb);
if (!rsnld.IsDone()) {
@@ -1264,6 +1271,27 @@ void ComputeInternalPoints
else {
vtestb = gp_Vec(0.,0.,0.);
}
count++;
if (count > 10)
{
if (count > 12)
{
dir1 = prevX - prevPrevX;
dir2 = X - prevX;
double d1n = dir1.Norm();
double d2n = dir2.Norm();
if (d1n > gp::Resolution() && d2n > gp::Resolution())
{
dir1 /= d1n;
dir2 /= d2n;
dot = dir1(1) * dir2(1) + dir1(2) * dir2(2);
if (Abs(dot + 1) < 1e-10)
revCount++;
}
}
prevPrevX = prevX;
prevX = X;
}
if ((vtestb.Magnitude() <= gp::Resolution())||
(Abs(X(1)-XInf(1)) <= toler(1)
&& Abs(X(2)-XInf(2)) <= toler(2)) ||
@@ -1278,6 +1306,11 @@ void ComputeInternalPoints
}
else {
XInf = X;
if (revCount > 10000)
{
//XInf = (X + prevPrevX)/2;
t = 0.75;
}
}
}
else { // on n est pas sur une solution

View File

@@ -24,8 +24,6 @@
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
static Standard_Real uinf,vinf,usup,vsup;
Standard_Integer Contap_HContTool::NbSamplesV
(const Handle(Adaptor3d_HSurface)& S,
const Standard_Real ,
@@ -125,7 +123,7 @@ Standard_Integer Contap_HContTool::NbSamplesU
}
Standard_Integer Contap_HContTool::NbSamplePoints
(const Handle(Adaptor3d_HSurface)& S)
(const Handle(Adaptor3d_HSurface)& S, Standard_Real& uinf, Standard_Real& vinf, Standard_Real& usup, Standard_Real& vsup)
{
uinf = S->FirstUParameter();
usup = S->LastUParameter();
@@ -175,7 +173,11 @@ Standard_Integer Contap_HContTool::NbSamplePoints
void Contap_HContTool::SamplePoint (const Handle(Adaptor3d_HSurface)& S,
const Standard_Integer Index,
Standard_Real& U,
Standard_Real& V )
Standard_Real& V,
const Standard_Real& uinf,
const Standard_Real& vinf,
const Standard_Real& usup,
const Standard_Real& vsup)
{
if(S->GetType() == GeomAbs_BSplineSurface) {
Standard_Integer nbIntU = NbSamplesU(S,uinf,usup)/3;

View File

@@ -44,9 +44,10 @@ public:
Standard_EXPORT static Standard_Integer NbSamplesV (const Handle(Adaptor3d_HSurface)& S, const Standard_Real v1, const Standard_Real v2);
Standard_EXPORT static Standard_Integer NbSamplePoints (const Handle(Adaptor3d_HSurface)& S);
Standard_EXPORT static Standard_Integer NbSamplePoints (const Handle(Adaptor3d_HSurface)& S, Standard_Real& uinf, Standard_Real& vinf, Standard_Real& usup, Standard_Real& vsup);
Standard_EXPORT static void SamplePoint (const Handle(Adaptor3d_HSurface)& S, const Standard_Integer Index, Standard_Real& U, Standard_Real& V);
Standard_EXPORT static void SamplePoint (const Handle(Adaptor3d_HSurface)& S, const Standard_Integer Index, Standard_Real& U, Standard_Real& V,
const Standard_Real& uinf, const Standard_Real& vinf, const Standard_Real& usup, const Standard_Real& vsup);
//! Returns True if all the intersection point and edges
//! are known on the Arc.

View File

@@ -42,13 +42,14 @@ void Contap_SurfFunction::Set(const Handle(Adaptor3d_HSurface)& S)
{
mySurf = S;
Standard_Integer i;
Standard_Integer nbs = Contap_HContTool::NbSamplePoints(S);
Standard_Real uinf,vinf,usup,vsup;
Standard_Integer nbs = Contap_HContTool::NbSamplePoints(S,uinf,vinf,usup,vsup);
Standard_Real U,V;
gp_Vec norm;
if (nbs > 0) {
myMean = 0.;
for (i = 1; i <= nbs; i++) {
Contap_HContTool::SamplePoint(S,i,U,V);
Contap_HContTool::SamplePoint(S,i,U,V,uinf,vinf,usup,vsup);
// Adaptor3d_HSurfaceTool::D1(S,U,V,solpt,d1u,d1v);
// myMean = myMean + d1u.Crossed(d1v).Magnitude();
Contap_SurfProps::Normale(S,U,V,solpt,norm);

View File

@@ -112,3 +112,13 @@ TopoDS_Shape HLRAppli_ReflectLines::GetResult() const
{
return GetCompoundOf3dEdges(HLRBRep_OutLine, Standard_True, Standard_True);
}
//=======================================================================
//function : GetCompoundOfFaces
//purpose :
//=======================================================================
TopoDS_Shape HLRAppli_ReflectLines::GetCompoundOfFaces(bool theMode,
TopTools_DataMapOfShapeShape& OrigFaceToProjFace ) const
{
HLRBRep_HLRToShape aHLRToShape( myHLRAlgo );
return aHLRToShape.CompoundOfFaces(theMode, OrigFaceToProjFace);
}

View File

@@ -26,6 +26,7 @@
#include <HLRBRep_TypeOfResultingEdge.hxx>
#include <TopoDS_Shape.hxx>
#include <Standard_Real.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
class TopoDS_Shape;
@@ -60,6 +61,9 @@ public:
const Standard_Boolean visible,
const Standard_Boolean In3d) const;
Standard_EXPORT TopoDS_Shape GetCompoundOfFaces(bool theMode,
TopTools_DataMapOfShapeShape& OrigFaceToProjFace) const;
protected:
@@ -70,8 +74,6 @@ protected:
private:
HLRAlgo_Projector myProjector;
Handle(HLRBRep_Algo) myHLRAlgo;
TopoDS_Shape myShape;

View File

@@ -899,7 +899,6 @@ void HLRBRep_Data::InitEdge (const Standard_Integer FI,
Standard_Boolean HLRBRep_Data::MoreEdge ()
{
if (iFaceTest) {
if (myFaceItr2.MoreEdge()) { // all edges must be tested if
myLE = myFaceItr2.Edge (); // the face is not a simple
@@ -927,61 +926,25 @@ Standard_Boolean HLRBRep_Data::MoreEdge ()
return myCurSortEd <= myNbrSortEd;
}
//=======================================================================
//function : NextEdge
//function : GetNextEdge
//purpose :
//=======================================================================
void HLRBRep_Data::NextEdge (const Standard_Boolean skip)
void HLRBRep_Data::GetNextEdge()
{
if (myCurSortEd > myNbrSortEd)
return;
for (;myCurSortEd <= myNbrSortEd;myCurSortEd++)
{
myLE = myEdgeIndices(myCurSortEd);
if (myEData(myLE).Vertical() || myEData(myLE).Status().AllHidden())
continue;
myLEData = &myEData(myLE);
if (myLEData->HideCount() > myHideCount-2)
continue;
if (skip) {
if (iFaceTest) myFaceItr2.NextEdge();
else myCurSortEd++;
}
if (!MoreEdge()) return;
if (iFaceTest) {
myLE = myFaceItr2.Edge ();
myLEOutLine = myFaceItr2.OutLine ();
myLEInternal = myFaceItr2.Internal();
myLEDouble = myFaceItr2.Double ();
myLEIsoLine = myFaceItr2.IsoLine ();
myLEData = &myEData(myLE);
myLEGeom = &myLEData->ChangeGeometry();
myLEMinMax = &myLEData->MinMax();
myLETol = myLEData->Tolerance();
myLEType = myLEGeom->GetType();
if (((HLRBRep_EdgeData*)myLEData)->Vertical() ||
(myLEDouble &&
((HLRBRep_EdgeData*)myLEData)->HideCount() == myHideCount-1))
NextEdge();
((HLRBRep_EdgeData*)myLEData)->HideCount(myHideCount-1);
return;
}
else {
myLE = Edge();
myLEOutLine = Standard_False;
myLEInternal = Standard_False;
myLEDouble = Standard_False;
myLEIsoLine = Standard_False;
myLEData = &myEData(myLE);
myLEGeom = &myLEData->ChangeGeometry();
myLEMinMax = &myLEData->MinMax();
myLETol = myLEData->Tolerance();
myLEType = myLEGeom->GetType();
}
if (((HLRBRep_EdgeData*)myLEData)->Vertical()) {
NextEdge();
return;
}
if (((HLRBRep_EdgeData*)myLEData)->HideCount() > myHideCount-2) {
NextEdge();
return;
}
if (((HLRBRep_EdgeData*)myLEData)->Status().AllHidden()) {
NextEdge();
return;
}
if (((iFaceMinMax->Max[0] - myLEMinMax->Min[0]) & 0x80008000) != 0 ||
myLEMinMax = &myLEData->MinMax();
if (((iFaceMinMax->Max[0] - myLEMinMax->Min[0]) & 0x80008000) != 0 ||
((myLEMinMax->Max[0] - iFaceMinMax->Min[0]) & 0x80008000) != 0 ||
((iFaceMinMax->Max[1] - myLEMinMax->Min[1]) & 0x80008000) != 0 ||
((myLEMinMax->Max[1] - iFaceMinMax->Min[1]) & 0x80008000) != 0 ||
@@ -995,15 +958,59 @@ void HLRBRep_Data::NextEdge (const Standard_Boolean skip)
((myLEMinMax->Max[5] - iFaceMinMax->Min[5]) & 0x80008000) != 0 ||
((iFaceMinMax->Max[6] - myLEMinMax->Min[6]) & 0x80008000) != 0 ||
((myLEMinMax->Max[6] - iFaceMinMax->Min[6]) & 0x80008000) != 0 ||
((iFaceMinMax->Max[7] - myLEMinMax->Min[7]) & 0x80008000) != 0) { //-- rejection en z
NextEdge();
((iFaceMinMax->Max[7] - myLEMinMax->Min[7]) & 0x80008000) != 0)
continue;
myLEGeom = &myLEData->ChangeGeometry();
myLETol = myLEData->Tolerance();
if (((HLRBRep_Surface*)iFaceGeom)->IsAbove
(iFaceBack,myLEGeom,(Standard_Real)myLETol))
continue;
break;
}
myLEOutLine = Standard_False;
myLEInternal = Standard_False;
myLEDouble = Standard_False;
myLEIsoLine = Standard_False;
myLEGeom = &myLEData->ChangeGeometry();
myLETol = myLEData->Tolerance();
myLEType = myLEGeom->GetType();
}
void HLRBRep_Data::NextEdge (const Standard_Boolean skip)
{
if (skip)
{
if (iFaceTest)
myFaceItr2.NextEdge();
else
myCurSortEd++;
}
if (iFaceTest && !MoreEdge())
return;
if (!iFaceTest)
{
GetNextEdge();
return;
}
if (((HLRBRep_Surface*)iFaceGeom)->IsAbove
(iFaceBack,myLEGeom,(Standard_Real)myLETol)) {
myLE = myFaceItr2.Edge ();
myLEOutLine = myFaceItr2.OutLine ();
myLEInternal = myFaceItr2.Internal();
myLEDouble = myFaceItr2.Double ();
myLEIsoLine = myFaceItr2.IsoLine ();
myLEData = &myEData(myLE);
myLEGeom = &myLEData->ChangeGeometry();
myLEMinMax = &myLEData->MinMax();
myLETol = myLEData->Tolerance();
myLEType = myLEGeom->GetType();
if (((HLRBRep_EdgeData*)myLEData)->Vertical() ||
(myLEDouble &&
((HLRBRep_EdgeData*)myLEData)->HideCount() == myHideCount-1))
NextEdge();
return;
}
((HLRBRep_EdgeData*)myLEData)->HideCount(myHideCount-1);
return; // edge is OK
}

View File

@@ -110,6 +110,8 @@ public:
Standard_EXPORT void NextEdge (const Standard_Boolean skip = Standard_True);
Standard_EXPORT void GetNextEdge();
//! Returns the current Edge
Standard_EXPORT Standard_Integer Edge() const;
@@ -236,7 +238,9 @@ private:
Standard_Boolean iFaceBack;
Standard_Boolean iFaceSimp;
Standard_Boolean iFaceSmpl;
public:
Standard_Boolean iFaceTest;
private:
Standard_Integer myHideCount;
Standard_Real myDeca[16];
Standard_Real mySurD[16];

View File

@@ -38,10 +38,12 @@ myFlags(0),mySize(0)
void HLRBRep_FaceData::Set (const TopoDS_Face& FG,
const TopAbs_Orientation Or,
const Standard_Boolean Cl,
const Standard_Integer NW)
const Standard_Integer NW,
const Standard_Boolean isInitSurf) //TODO isInitSurf can be deleted
{
Closed(Cl);
Geometry().Surface(FG);
if (isInitSurf)
Geometry().Surface(FG);
myTolerance = (Standard_ShortReal)(BRep_Tool::Tolerance(FG));
Orientation(Or);
Wires() = new HLRAlgo_WiresBlock(NW);

View File

@@ -46,7 +46,7 @@ public:
//! if the face belongs to a closed volume. <NW> is
//! the number of wires ( or block of edges ) of the
//! face.
Standard_EXPORT void Set (const TopoDS_Face& FG, const TopAbs_Orientation Or, const Standard_Boolean Cl, const Standard_Integer NW);
Standard_EXPORT void Set (const TopoDS_Face& FG, const TopAbs_Orientation Or, const Standard_Boolean Cl, const Standard_Integer NW, const Standard_Boolean isInitSurf);
//! Set <NE> the number of edges of the wire number
//! <WI>.

View File

@@ -28,6 +28,34 @@
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <BRepLib.hxx>
#include <BRepLib_MakeVertex.hxx>
#include <BRepTools.hxx>
#include <TopExp.hxx>
#include <IntTools_FClass2d.hxx>
#include <BRepTools_ReShape.hxx>
#include <Poly_MakeLoops.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <BndLib_Add2dCurve.hxx>
#include <Bnd_Box2d.hxx>
#include <BRepAdaptor_Curve2d.hxx>
#include <BRepGProp.hxx>
#include <GProp_GProps.hxx>
#include <NCollection_Handle.hxx>
#include <BRepBndLib.hxx>
#include <BOPTools_AlgoTools3D.hxx>
#include <IntTools_Context.hxx>
#include <BRepAlgoAPI_BuilderAlgo.hxx>
#include <NCollection_UBTree.hxx>
#include <Extrema_POnCurv2d.hxx>
#include <IntCurvesFace_ShapeIntersector.hxx>
#include <Extrema_ExtPC2d.hxx>
#include <HLRTopoBRep_OutLiner.hxx>
#include <Geom_Plane.hxx>
#include <BRepBndLib.hxx>
#include <TopTools_DataMapOfShapeReal.hxx>
#include <algorithm>
//=======================================================================
//function : HLRBRep_HLRToShape
//purpose :
@@ -250,3 +278,932 @@ HLRBRep_HLRToShape::DrawEdge (const Standard_Boolean visible,
}
}
}
//UBTree edge-point
typedef NCollection_UBTree <Standard_Integer, Bnd_Box2d> HLRVV_BndBoxTree;
class HLRVV_BndBoxTreeSelector : public HLRVV_BndBoxTree::Selector
{
public:
HLRVV_BndBoxTreeSelector( const TopTools_IndexedMapOfShape& theInpShapes,
double theMinDDist)
: myInpShapes(theInpShapes),
myMinDDist(theMinDDist),
myResId (-1),
myCId (-1)
{}
Standard_Boolean Reject (const Bnd_Box2d& theBox) const
{
double aCurDDist = theBox.SquareDistance(myCPnt);
if (aCurDDist > myMinDDist)
return true;
else
return false;
}
Standard_Boolean Accept (const Standard_Integer& theObj)
{
//extrema pnt <-> vertex
const TopoDS_Shape& aSh = myInpShapes(theObj);
if (theObj == myCId)
return Standard_False;
gp_Pnt aCVP = BRep_Tool::Pnt(TopoDS::Vertex(aSh));
gp_Pnt2d aCVP2d(aCVP.X(), aCVP.Y());
double aDD = aCVP2d.SquareDistance(myCPnt);
if (aDD < myMinDDist)
{
myMinDDist = aDD;
myResId = theObj;
}
return Standard_True;
}
void Reset(double theMinDDist)
{
myMinDDist = theMinDDist;
myResId = -1;
myCId = -1;
}
void SetCurrentPoint( int id )
{
gp_Pnt CP = BRep_Tool::Pnt(TopoDS::Vertex(myInpShapes(id)));
myCPnt.SetX(CP.X());
myCPnt.SetY(CP.Y());
myCId = id;
}
double GetMinDDist() const
{
return myMinDDist;
}
int GetResVId() const
{
return myResId;
}
private:
HLRVV_BndBoxTreeSelector(const HLRVV_BndBoxTreeSelector& );
HLRVV_BndBoxTreeSelector& operator=(const HLRVV_BndBoxTreeSelector& );
private:
const TopTools_IndexedMapOfShape& myInpShapes;
gp_Pnt2d myCPnt;
double myMinDDist;
int myResId;
int myCId;
};
///
//UBTree edge-point
typedef NCollection_UBTree <Standard_Integer, Bnd_Box2d> HLRVE_BndBoxTree;
class HLRVE_BndBoxTreeSelector : public HLRVE_BndBoxTree::Selector
{
public:
HLRVE_BndBoxTreeSelector(
const NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& theEdgeAdapt,
double theMinDDist)
: myEdgeAdapt (theEdgeAdapt),
myMinDDist(theMinDDist)
{}
Standard_Boolean Reject (const Bnd_Box2d& theBox) const
{
double aCurDDist = theBox.SquareDistance(myCPnt);
if (aCurDDist > myMinDDist)
return true;
else
return false;
}
Standard_Boolean Accept (const Standard_Integer& theObj)
{
const BRepAdaptor_Curve2d& adapt = myEdgeAdapt(theObj);
Extrema_ExtPC2d aExtPC(myCPnt, adapt, adapt.FirstParameter(), adapt.LastParameter());
if (aExtPC.IsDone() && aExtPC.NbExt() > 0 )
{
NCollection_Handle<Extrema_POnCurv2d> aPSol;// = aExtPC.Point(1);
double aMinDD = Precision::Infinite();
double aFp = adapt.FirstParameter();
double aLp = adapt.LastParameter();
for ( Standard_Integer i = 1; i <= aExtPC.NbExt(); i++)
{
double aCDD = aExtPC.SquareDistance(i);
Extrema_POnCurv2d aCurSol = aExtPC.Point(i);
if (Abs(aCurSol.Parameter() - aFp) < Precision::Confusion() ||
Abs(aCurSol.Parameter() - aLp) < Precision::Confusion()) //TODO it's better to use tolerance of vertex here
continue;
if ( aCDD < aMinDD)
{
aMinDD = aCDD;
aPSol = new Extrema_POnCurv2d(aExtPC.Point(i));
}
}
if (aMinDD < myMinDDist)
{
myMinDDist = aMinDD;
myEARes = adapt;
if (!myPSolRes)
myPSolRes = new Extrema_POnCurv2d( *aPSol );
else
myPSolRes->SetValues(aPSol->Parameter(), aPSol->Value());
}
}
return Standard_True;
}
void Reset(double theMinDDist)
{
myMinDDist = theMinDDist;
myPSolRes.Nullify();
}
void SetCurrentPoint( const gp_Pnt& thePnt )
{
myCPnt.SetX(thePnt.X());
myCPnt.SetY(thePnt.Y());
}
bool GetPResult(Extrema_POnCurv2d& thePSolRes, BRepAdaptor_Curve2d& theERes) const
{
if (!myPSolRes.IsNull())
{
thePSolRes = *myPSolRes;
theERes = myEARes;
return true;
}
else
return false;
}
private:
HLRVE_BndBoxTreeSelector(const HLRVE_BndBoxTreeSelector& );
HLRVE_BndBoxTreeSelector& operator=(const HLRVE_BndBoxTreeSelector& );
private:
const NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& myEdgeAdapt;
gp_Pnt2d myCPnt;
double myMinDDist;
NCollection_Handle<Extrema_POnCurv2d> myPSolRes;
BRepAdaptor_Curve2d myEARes;
};
//! deriatives of the edges on both ends
struct BRepFill_TangentLinkInfo
{
gp_Dir2d myD1L;
gp_Dir2d myD1F;
};
class BRepFill_PolyHelper : public Poly_MakeLoops2D::Helper
{
public:
BRepFill_PolyHelper( const NCollection_DataMap<Poly_MakeLoops2D::Link, BRepFill_TangentLinkInfo>& mL2TI,
const NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>& themNode2ListOfLinks) :
myL2TI (mL2TI),
mymNode2ListOfLinks (themNode2ListOfLinks)
{
};
virtual const Poly_MakeLoops2D::ListOfLink& GetAdjacentLinks (Standard_Integer theNode) const
{
return mymNode2ListOfLinks(theNode);
}
virtual Standard_Boolean GetFirstTangent(const Poly_MakeLoops2D::Link& theLink, gp_Dir2d& theDir) const
{
if (theLink.flags & Poly_MakeLoops2D::LF_Reversed)
theDir = -myL2TI(theLink).myD1L;
else
theDir = myL2TI(theLink).myD1F;
return Standard_True;
}
virtual Standard_Boolean GetLastTangent(const Poly_MakeLoops2D::Link& theLink, gp_Dir2d& theDir) const
{
if (theLink.flags & Poly_MakeLoops2D::LF_Reversed)
theDir = -myL2TI(theLink).myD1F;
else
theDir = myL2TI(theLink).myD1L;
return Standard_True;
}
private:
BRepFill_PolyHelper& operator= (const BRepFill_PolyHelper &theOther);
private:
const NCollection_DataMap<Poly_MakeLoops2D::Link, BRepFill_TangentLinkInfo>& myL2TI;
const NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>& mymNode2ListOfLinks;
};
typedef NCollection_UBTree <Standard_Integer, Bnd_Box> HLRFL_BndBoxTree;
class HLRFL_BndBoxTreeSelector : public HLRFL_BndBoxTree::Selector
{
public:
struct FaceParam
{
TopoDS_Face myF;
double LPar;
};
HLRFL_BndBoxTreeSelector(const TopTools_IndexedMapOfShape& theFMap, bool theMode)
: HLRFL_BndBoxTreeSelector::Selector(),
myFMap (theFMap),
myIntersectors(1, theFMap.Size()),
myMode (theMode)
{
for (int i =1; i <= myIntersectors.Size(); i++)
myIntersectors(i) = NULL;
}
~HLRFL_BndBoxTreeSelector()
{
for (int i =1; i <= myIntersectors.Size(); i++)
{
IntCurvesFace_ShapeIntersector* an_inter = myIntersectors(i);
if (an_inter)
delete an_inter;
}
}
Standard_Boolean Reject (const Bnd_Box& theBox) const
{
return theBox.IsOut (myLine);
}
Standard_Boolean Accept (const Standard_Integer& theObj)
{
if (theObj > myFMap.Extent())
return Standard_False;
const TopoDS_Face& F = TopoDS::Face(myFMap(theObj));
IntCurvesFace_ShapeIntersector* an_inter = myIntersectors(theObj);
if (!an_inter)
{
an_inter = new IntCurvesFace_ShapeIntersector();
an_inter->Load(F, Precision::Confusion());
}
an_inter->Perform(myLine, -Precision::Infinite(), Precision::Infinite()); //TODO trim the line according to bnd box of face
if (an_inter->IsDone() && an_inter->NbPnt())
{
for (int i=1; i <= an_inter->NbPnt(); i++)
{
FaceParam fp;
fp.LPar = an_inter->WParameter(i);
fp.myF = an_inter->Face(i);
myRParams.push_back(fp);
}
if (!myMode)
myStop = 1;
}
return Standard_True;
//int nbpnt = an_inter->.NbPnt();
}
void SetLine (const gp_Lin& theLine)
{
myLine = theLine;
}
const std::vector<FaceParam>& GetRParams () const
{
return myRParams;
}
void ResetResult()
{
myRParams.clear();
}
private:
HLRFL_BndBoxTreeSelector(const HLRFL_BndBoxTreeSelector& );
HLRFL_BndBoxTreeSelector& operator=(const HLRFL_BndBoxTreeSelector& );
private:
const TopTools_IndexedMapOfShape& myFMap;
gp_Lin myLine;
NCollection_Array1<IntCurvesFace_ShapeIntersector*> myIntersectors;
std::vector<FaceParam> myRParams;
bool myMode; //if true => find all line-face intersections; otherwise - find any and stop the search
};
static bool FuseVE(TopoDS_Shape& theRes)
{
TopTools_IndexedMapOfShape allE;
TopExp::MapShapes(theRes, TopAbs_EDGE, allE);
TopTools_ListOfShape aLSE;
for (int i = 1; i <= allE.Extent(); i++ )
aLSE.Append(allE(i));
Standard_Real aFV = 0;
BRepAlgoAPI_BuilderAlgo aBlr;
aBlr.SetArguments(aLSE);
aBlr.SetRunParallel(Standard_True);
aBlr.SetFuzzyValue(aFV);
aBlr.Build();
if (aBlr.HasErrors())
{
aBlr.DumpErrors(cout);
return false;
}
theRes = aBlr.Shape();
return true;
}
static void ProcessHVertices(TopoDS_Shape& theRes,
NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& theEdAd,
NCollection_DataMap<TopoDS_Edge, Bnd_Box2d, TopTools_ShapeMapHasher>& theEdBnd2d )
{
BRepTools_ReShape reshaper;
///hanging vertices => find closely located point on some edge or vertex
TopoDS_Face aDraftPrFace;
BRep_Builder().MakeFace(aDraftPrFace, BRepLib::Plane(), Precision::Confusion());
TopTools_IndexedDataMapOfShapeListOfShape M;
TopExp::MapShapesAndAncestors(theRes, TopAbs_VERTEX, TopAbs_EDGE, M);
TopTools_IndexedMapOfShape HV;
for (int i = 1; i <= M.Extent(); i++)
if (M(i).Extent() == 1)
HV.Add(M.FindKey(i));
//
TopTools_IndexedMapOfShape VV, EE;
TopExp::MapShapes(theRes, TopAbs_VERTEX, VV);
TopExp::MapShapes(theRes, TopAbs_EDGE, EE);
//
//vertex-vertex extrema
NCollection_UBTree <Standard_Integer, Bnd_Box2d> aTreeVV;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFillerVV (aTreeVV);
for (Standard_Integer i = 1; i <= VV.Extent(); i++)
{
const TopoDS_Vertex& aV = TopoDS::Vertex(VV(i));
Bnd_Box2d aBB;
gp_Pnt aPV = BRep_Tool::Pnt(aV);
aBB.Add(gp_Pnt2d(aPV.X(), aPV.Y()));
aBB.Enlarge(BRep_Tool::Tolerance(aV));
aTreeFillerVV.Add(i, aBB);
}
aTreeFillerVV.Fill();
HLRVV_BndBoxTreeSelector aSelectorVV(VV, Precision::Infinite());
//vertex-edge extrema
NCollection_UBTree <Standard_Integer, Bnd_Box2d> aTreeVE;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box2d> aTreeFillerVE (aTreeVE);
int nbEE = EE.Extent();
//NCollection_Array1<BRepAdaptor_Curve2d> anEdgeAdapters(1, nbEE);
for (Standard_Integer i = 1; i <= nbEE; i++)
{
const TopoDS_Edge& anE = TopoDS::Edge(EE(i));
Bnd_Box2d aBB;
theEdAd.Add(anE, BRepAdaptor_Curve2d(anE, aDraftPrFace));
BndLib_Add2dCurve::Add(*theEdAd.Seek(anE), 0, aBB);
theEdBnd2d.Bind(anE, aBB);
aTreeFillerVE.Add(i, aBB);
}
aTreeFillerVE.Fill();
HLRVE_BndBoxTreeSelector aSelectorVE(theEdAd, Precision::Infinite()); //min dist doesn't matter here
//
TopTools_IndexedMapOfShape toadd, torem;//temp
for (int i = 1; i <= HV.Extent(); i++ )
{
const TopoDS_Vertex& CHV = TopoDS::Vertex(HV(i));
gp_Pnt CHVPnt = BRep_Tool::Pnt(CHV);
//
int id = VV.FindIndex(CHV);
aSelectorVV.Reset(Precision::Infinite());
aSelectorVV.SetCurrentPoint( id );
/*int resVV =*/ aTreeVV.Select(aSelectorVV);
double aMinDDistReached = aSelectorVV.GetMinDDist();
TopoDS_Vertex aResV = TopoDS::Vertex(VV(aSelectorVV.GetResVId()));
//
aSelectorVE.Reset(aMinDDistReached);
aSelectorVE.SetCurrentPoint( CHVPnt );
/*int resVE = */aTreeVE.Select(aSelectorVE);
Extrema_POnCurv2d aPSolRes;
BRepAdaptor_Curve2d aResEA;
bool VEFound = aSelectorVE.GetPResult(aPSolRes, aResEA);
if (VEFound)
{
///if (BRep_Tool::Degenerated(E)) //can be degenerted??
double aPar = aPSolRes.Parameter();
const TopoDS_Edge& aResE = aResEA.Edge();
TopoDS_Edge aDE1 = TopoDS::Edge(aResE.EmptyCopied().Oriented(TopAbs_FORWARD));
TopoDS_Edge aDE2 = TopoDS::Edge(aResE.EmptyCopied().Oriented(TopAbs_FORWARD));
TopoDS_Vertex aFV, aLV;
TopExp::Vertices(aResE, aFV, aLV);
double aFP = aResEA.FirstParameter();
double aLP = aResEA.LastParameter();
gp_Pnt2d aResP2d = aResEA.Value(aPar);
gp_Pnt aResP3d(aResP2d.X(), aResP2d.Y(), 0.0);
TopoDS_Vertex aDummyV = BRepLib_MakeVertex(aResP3d).Vertex();
//
NCollection_List<TopoDS_Shape> nls;
nls.Append(aDummyV);
nls.Append(CHV);
gp_Pnt aNC;
double aNTol;
BRepLib::BoundingVertex(nls, aNC, aNTol);
gp_Pnt aFVP = BRep_Tool::Pnt(aFV);
gp_Pnt aLVP = BRep_Tool::Pnt(aLV);
if (aFVP.Distance(aNC) < aNTol*1e10 ||
aLVP.Distance(aNC) < aNTol*1e10)
{
nls.RemoveFirst();
nls.Append(aResV);
BRepLib::BoundingVertex(nls, aNC, aNTol);
BRep_Builder().UpdateVertex(aResV, aNC, aNTol);
reshaper.Replace(CHV, aResV.Oriented(CHV.Orientation()));
if (HV.Contains(aResV)) //if the closest vertex lays on edge => never contains in HV
HV.RemoveKey(aResV);
}
else
{
BRep_Builder().UpdateVertex(CHV, aNC, aNTol);
BRep_Builder().Range(aDE1, aFP, aPar);
BRep_Builder().Add(aDE1, aFV.Oriented(TopAbs_FORWARD));
BRep_Builder().Add(aDE1, CHV.Oriented(TopAbs_REVERSED));
//
BRep_Builder().Range(aDE2, aPar, aLP );
BRep_Builder().Add(aDE2, CHV.Oriented(TopAbs_FORWARD));
BRep_Builder().Add(aDE2, aLV.Oriented(TopAbs_REVERSED));
//
///TODO temp
torem.Add(aResE);
toadd.Add(aDE1);
toadd.Add(aDE2);
//TopoDS_Compound aResCmp;
//BRep_Builder().MakeCompound(aResCmp);
//BRep_Builder().Add(aResCmp, aDE1);
//BRep_Builder().Add(aResCmp, aDE2);
//
//TopoDS_Wire aResW;
//BRep_Builder().MakeWire(aResW);
//BRep_Builder().Add(aResW, aDE1);
//BRep_Builder().Add(aResW, aDE2);
//TopoDS_Wire aResW = BRepBuilderAPI_MakeWire(aDE1, aDE2).Wire(); //this will control proper sharing and tolerance matching between vertices
/*{ //DEB
TopTools_IndexedMapOfShape VVVV;
TopExp::MapShapes(aResW, TopAbs_VERTEX, VVVV);
//cout << VVVV.Extent() << endl;
}*/
//aResW.Orientation(aResE.Orientation());
//reshape.Replace(aResE, aResCmp);
}
}
else
{
NCollection_List<TopoDS_Shape> nls; //TODO move to ext func
nls.Append(CHV);
nls.Append(aResV);
gp_Pnt aNC;
double aNTol;
BRepLib::BoundingVertex(nls, aNC, aNTol);
BRep_Builder().UpdateVertex(aResV, aNC, aNTol);
reshaper.Replace(CHV, aResV.Oriented(CHV.Orientation()));
if (HV.Contains(aResV)) //if the closest vertex lays on edge => never contains in HV
HV.RemoveKey(aResV);
}
}
//DEB
for (int i =1; i<= torem.Extent() ;i++)
BRep_Builder().Remove(theRes, torem(i));
//DEB
for (int i =1; i<= toadd.Extent() ;i++)
BRep_Builder().Add(theRes, toadd(i));
//
theRes = reshaper.Apply(theRes); //replace only vertices
}
static void FillNode2LLMap(Standard_Integer NewNode, const Poly_MakeLoops2D::Link& NewLink,
NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>& mNode2ListOfLinks)
{
if (!mNode2ListOfLinks.IsBound(NewNode))
mNode2ListOfLinks.Bound(NewNode, Poly_MakeLoops2D::ListOfLink())->Append(NewLink);
else
mNode2ListOfLinks(NewNode).Append(NewLink);
}
static TopAbs_State GetStateOfSamplePoint(const TopoDS_Face& ff2,
const IntTools_FClass2d& fclass,
const Bnd_Box2d& fbnd)
{
TopExp_Explorer exp(ff2, TopAbs_EDGE); //should contains at least one edge
TopoDS_Edge fe2 = TopoDS::Edge(exp.Current());
BRepAdaptor_Curve2d afe2(fe2, ff2);
gp_Pnt2d middlepoint = afe2.Value((afe2.LastParameter() + afe2.FirstParameter()) / 2.0);
Bnd_Box bb3d;
BRepBndLib::Add(ff2, bb3d);
Bnd_Box2d bb2d;
bb2d.Set(gp_Pnt2d(bb3d.CornerMin().X(), bb3d.CornerMin().Y()));
bb2d.Add(gp_Pnt2d(bb3d.CornerMax().X(), bb3d.CornerMax().Y()));
if (bb2d.IsOut(middlepoint))
return TopAbs_OUT;
else
return fclass.Perform(middlepoint);
}
bool HLRBRep_ParComp(const HLRFL_BndBoxTreeSelector::FaceParam& a,
const HLRFL_BndBoxTreeSelector::FaceParam& b)
{
return a.LPar < b.LPar;
}
static TopoDS_Shape ProcessLoops(const TopoDS_Shape& theRes,
NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher>& anEdAd,
NCollection_DataMap<TopoDS_Edge, Bnd_Box2d, TopTools_ShapeMapHasher> theEdBnd2d,
HLRAlgo_Projector& projector,
const TopTools_ListOfShape& anOrigShapes,
bool theMode,
TopTools_DataMapOfShapeShape& OrigFaceToProjFace )
{
NCollection_List<TopoDS_Wire> theLoops;
NCollection_List<TopoDS_Wire> SelfLoops;
NCollection_DataMap<TopoDS_Shape, Bnd_Box2d, TopTools_ShapeMapHasher> aShToBnd2d;
TopoDS_Face aDraftPrFace;
BRep_Builder().MakeFace(aDraftPrFace, BRepLib::Plane(), Precision::Confusion());
TopTools_IndexedMapOfShape mN2V;
TopExp::MapShapes(theRes, TopAbs_VERTEX, mN2V);
NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink> mNode2ListOfLinks;
NCollection_DataMap<Poly_MakeLoops2D::Link, BRepFill_TangentLinkInfo> mL2TI;
//Create links for Poly_MakeLoops algo and bind them to the existing edges
NCollection_DataMap<Poly_MakeLoops2D::Link, TopoDS_Edge> mL2E;
Standard_Integer LastIndV = mN2V.Extent();
TopExp_Explorer ExpE;
ExpE.Init(theRes, TopAbs_EDGE);
for (; ExpE.More(); ExpE.Next())
{
const TopoDS_Edge& E = TopoDS::Edge(ExpE.Current());
// If edge contains only one vertex => self loop (should be non degenerated)
TopoDS_Vertex FV, LV;
FV = TopExp::FirstVertex(E, Standard_True);
LV = TopExp::LastVertex(E, Standard_True);
if (FV.IsSame(LV))
{
if (!BRep_Tool::Degenerated(E))
{
const TopoDS_Wire& aW = BRepLib_MakeWire(E).Wire();
SelfLoops.Append(aW);
Bnd_Box2d aBB;
BndLib_Add2dCurve::Add(BRepAdaptor_Curve2d(E, aDraftPrFace), 0, aBB);
aShToBnd2d.Bind(aW, aBB);
}
continue;
}
const BRepAdaptor_Curve2d* anAd = anEdAd.Seek(E);
if (!anAd)
{
anEdAd.Add(E, BRepAdaptor_Curve2d(E, aDraftPrFace));
anAd = anEdAd.Seek(E);
Bnd_Box2d aBB;
BndLib_Add2dCurve::Add(*anEdAd.Seek(E), 0, aBB);
theEdBnd2d.Bind(E, aBB);
}
//NCollection_Handle<BRepAdaptor_Curve2d> adapt = new BRepAdaptor_Curve2d(E, aDraftPrFace);
gp_Pnt2d Pnt;
gp_Vec2d Vec;
gp_Dir2d D1F, D1L;
if (anAd->Curve().IsNull())
continue;
TopAbs_Orientation EOri = E.Orientation();
if (EOri == TopAbs_FORWARD)
{
anAd->D1(anAd->FirstParameter(), Pnt, Vec);
if (Vec.SquareMagnitude() <= gp::Resolution())
anAd->D1(anAd->FirstParameter() + Precision::Confusion(), Pnt, Vec);
D1F.SetCoord(Vec.X(), Vec.Y());
anAd->D1(anAd->LastParameter(), Pnt, Vec);
if (Vec.SquareMagnitude() <= gp::Resolution())
anAd->D1(anAd->LastParameter() - Precision::Confusion(), Pnt, Vec);
D1L.SetCoord(Vec.X(), Vec.Y());
}
else if (EOri == TopAbs_REVERSED)
{
anAd->D1(anAd->LastParameter(), Pnt, Vec);
if (Vec.SquareMagnitude() <= gp::Resolution())
anAd->D1(anAd->LastParameter() - Precision::Confusion(), Pnt, Vec);
D1F.SetCoord(-Vec.X(), -Vec.Y());
anAd->D1(anAd->FirstParameter(), Pnt, Vec);
if (Vec.SquareMagnitude() <= gp::Resolution())
anAd->D1(anAd->FirstParameter() + Precision::Confusion(), Pnt, Vec);
D1L.SetCoord(-Vec.X(), -Vec.Y());
}
else
continue;
Standard_Integer Node1 = mN2V.FindIndex(FV);
Standard_Integer Node2 = mN2V.FindIndex(LV);
Poly_MakeLoops2D::Link aLink(Node1, Node2);
aLink.flags = Poly_MakeLoops2D::LF_Both;
if (!mL2E.IsBound(aLink))
{
mL2E.Bind(aLink, E);
FillNode2LLMap(Node1, aLink, mNode2ListOfLinks);
FillNode2LLMap(Node2, aLink, mNode2ListOfLinks);
BRepFill_TangentLinkInfo* Info = mL2TI.Bound(aLink, BRepFill_TangentLinkInfo());
Info->myD1F = D1F;
Info->myD1L = D1L;
}
else
{
//link have been met twise. This may indicate that it is has
//opposite direction now. Try to divide it (node1, node2) => (node1, ind) + (ind, node2)
//so it can be passed to loop maker
LastIndV++;
Poly_MakeLoops2D::Link aLink1(Node1, LastIndV);
aLink1.flags = Poly_MakeLoops2D::LF_Both;
Poly_MakeLoops2D::Link aLink2(LastIndV, Node2);
aLink2.flags = Poly_MakeLoops2D::LF_Both;
mL2E.Bind(aLink1, E);
mL2E.Bind(aLink2, TopoDS_Edge()); //indicates that one edge represented as two links
FillNode2LLMap(Node1, aLink1, mNode2ListOfLinks);
FillNode2LLMap(Node2, aLink2, mNode2ListOfLinks);
FillNode2LLMap(LastIndV, aLink1, mNode2ListOfLinks);
FillNode2LLMap(LastIndV, aLink2, mNode2ListOfLinks);
BRepFill_TangentLinkInfo* Info1 = mL2TI.Bound(aLink1, BRepFill_TangentLinkInfo());
Info1->myD1F = D1F;
Info1->myD1L = gp_Dir2d(1., 1.);
BRepFill_TangentLinkInfo* Info2 = mL2TI.Bound(aLink2, BRepFill_TangentLinkInfo());
Info2->myD1F = gp_Dir2d(1., 1.);
Info2->myD1L = D1L;
}
}
//DEBUG: print D1F
/*{
NCollection_DataMap<Standard_Integer, Poly_MakeLoops2D::ListOfLink>::Iterator it(mNode2ListOfLinks);
for (;it.More();it.Next())
{
int nK = it.Key();
Poly_MakeLoops2D::ListOfLink links = it.Value();
Poly_MakeLoops2D::ListOfLink::Iterator itl(links);
cout << "next:" << endl;
for (;itl.More();itl.Next())
{
BRepFill_TangentLinkInfo linfo = mL2TI(itl.Value());
cout << linfo.myD1F.X() << " " << linfo.myD1F.Y() << endl;
TopoDS_Edge eee = mL2E(itl.Value());
}
}
*/
//
BRepFill_PolyHelper helper(mL2TI, mNode2ListOfLinks);
Poly_MakeLoops2D aLoopMaker(1, &helper, NCollection_BaseAllocator::CommonBaseAllocator() );
for (NCollection_DataMap<Poly_MakeLoops2D::Link, TopoDS_Edge>::Iterator aMapIt (mL2E); aMapIt.More(); aMapIt.Next())
aLoopMaker.AddLink(aMapIt.Key());
aLoopMaker.Perform(); //try to find loops
Standard_Integer NbLoops = aLoopMaker.GetNbLoops();
Standard_Integer NbHangs = aLoopMaker.GetNbHanging();
cout << "NbLoops=" << NbLoops << endl;
cout << "NbHangs=" << NbHangs << endl;
// if (NbLoops == 0 || NbHangs != 0 )
// return Standard_False;
theLoops.Append(SelfLoops);
for (Standard_Integer i = 1; i <= NbLoops; i++) //loops to wires
{
Poly_MakeLoops2D::Loop aLoop = aLoopMaker.GetLoop(i);
Poly_MakeLoops2D::Loop::Iterator it(aLoop);
BRepBuilderAPI_MakeWire aWM;
Bnd_Box2d aWBox2d;
TopoDS_Edge E;
for (;it.More(); it.Next())
{
const Poly_MakeLoops2D::Link& Link = it.Value();
E = mL2E(Link);
if (Link.flags & Poly_MakeLoops2D::LF_Reversed)
E.Reverse();
//if null => probably this edge was passed as two links (based on the same edge); so skip this edge
if (!E.IsNull())
{
aWM.Add(E);
aWBox2d.Add(theEdBnd2d(E));
}
}
if (aWM.IsDone())
{
TopoDS_Wire W = aWM.Wire();
if (W.Closed())
{
theLoops.Append(W);
aShToBnd2d.Bind(W, aWBox2d);
}
}
}
//DEBUG
/* Poly_MakeLoops2D::ListOfLink theHLinks;
aLoopMaker.GetHangingLinks(theHLinks);
Poly_MakeLoops2D::ListOfLink::Iterator itt(theHLinks);
TopoDS_Compound cmpH;BRep_Builder().MakeCompound(cmpH);
for (; itt.More();itt.Next())
{
Poly_MakeLoops2D::Link alink = itt.Value();
const Poly_MakeLoops2D::Link& Link = itt.Value();
TopoDS_Edge E = mL2E(Link);
if (Link.flags & Poly_MakeLoops2D::LF_Reversed)
E.Reverse();
//if null => probably this edge was passed as two links (based on the same edge); so skip this edge
if (!E.IsNull())
BRep_Builder().Add(cmpH, E);
}*/
//
IntTools_Context context1;// = new IntTools_Context();
NCollection_List<TopoDS_Wire>::Iterator itL(theLoops);
NCollection_IndexedDataMap<TopoDS_Shape, double> lf1, lf2;
for (; itL.More(); itL.Next())
{
const TopoDS_Wire& aW = itL.Value();
if (aW.IsNull())
continue;
TopoDS_Face ff;
BRep_Builder().MakeFace(ff, BRepLib::Plane(), Precision::Confusion());
//plane is static; pcurves of edges are already based on this plane
BRep_Builder().Add(ff, aW);
aShToBnd2d(aW).Enlarge(0.001);
aShToBnd2d.Bind(ff, aShToBnd2d(aW)); //bndbox still the same
GProp_GProps pr;
BRepGProp::SurfaceProperties(ff, pr);
Standard_Real CurMass = pr.Mass();
if (Abs(CurMass) < 1e-10) //?? TODO
continue;
if (CurMass >= 0)
lf1.Add(ff, CurMass);
else
lf2.Add(ff, CurMass);
}
NCollection_IndexedDataMap<TopoDS_Face, NCollection_List<TopoDS_Face>> FaceToIntWires;
for (int i = 1; i <= lf1.Size() && !lf2.IsEmpty(); i++)
{
//NCollection_Handle<BRepTopAdaptor_FClass2d> fclass;
NCollection_Sequence<TopoDS_Face> intf;
const TopoDS_Face& ff1 = TopoDS::Face(lf1.FindKey(i));
for (int j=1;j<= lf2.Size();j++)
{
double pm = lf1.FindFromIndex(i);
double nm = lf2.FindFromIndex(j);
if (pm < -nm)
continue;
const TopoDS_Face& ff2 = TopoDS::Face(lf2.FindKey(j));
//if (!fclass)
// fclass = new BRepTopAdaptor_FClass2d(ff1, Precision::Confusion());
IntTools_FClass2d& fclass = context1.FClass2d(ff1);
Bnd_Box2d fbnd = aShToBnd2d(ff1);
TopAbs_State st = GetStateOfSamplePoint(ff2, fclass, fbnd);
if (st == TopAbs_IN)
intf.Append(ff2);
}
NCollection_Map<int> intfInd;
for (int i = 1; i<= intf.Size();i++)
{
if (intfInd.Contains(i))
continue;
//BRepTopAdaptor_FClass2d fclassInt(intf(i), Precision::Confusion());
IntTools_FClass2d& fclassInt = context1.FClass2d(intf(i));
Bnd_Box2d fbndi = aShToBnd2d(intf(i));
for (int j=1; j<= intf.Size();j++)
{
if (i==j)
continue;
if (intfInd.Contains(j))
continue;
TopAbs_State st = GetStateOfSamplePoint(intf(j), fclassInt, fbndi);
if (st == TopAbs_OUT) //note that intf-faces are holes
intfInd.Add(j);
}
}
FaceToIntWires.Add(ff1, NCollection_List<TopoDS_Face>());
NCollection_List<TopoDS_Face>& nl = FaceToIntWires.ChangeFromKey(ff1);
for (int i = 1; i<= intf.Size();i++)
{
if (intfInd.Contains(i))
continue;
nl.Append(intf(i));
}
}
TopoDS_Compound aResCmp;
BRep_Builder().MakeCompound(aResCmp);
TopTools_ListIteratorOfListOfShape itOrS(anOrigShapes);
TopTools_IndexedMapOfShape anOrigFaces;
for (;itOrS.More();itOrS.Next())
TopExp::MapShapes(itOrS.Value(), TopAbs_FACE, anOrigFaces);
NCollection_UBTree <Standard_Integer, Bnd_Box> aTreeFL;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFillerFL (aTreeFL);
for (Standard_Integer i = 1; i <= anOrigFaces.Extent(); i++)
{
const TopoDS_Face& aF = TopoDS::Face(anOrigFaces(i));
Bnd_Box aBB;
BRepBndLib::Add(aF, aBB);
aTreeFillerFL.Add(i, aBB);
}
aTreeFillerFL.Fill();
HLRFL_BndBoxTreeSelector aSelFL(anOrigFaces, theMode);
for (int i = 1; i <= FaceToIntWires.Extent(); i++)
{
TopoDS_Face cf = FaceToIntWires.FindKey(i);
NCollection_List<TopoDS_Face>::Iterator it(FaceToIntWires.FindFromIndex(i));
for (;it.More();it.Next())
{
TopoDS_Face ff = it.Value();
TopoDS_Iterator it(ff);
TopoDS_Shape int_wire = it.Value();
BRep_Builder().Add(cf, int_wire);
}
gp_Pnt2d p2d;
gp_Pnt p3d;
TopExp_Explorer exp(cf, TopAbs_EDGE);
Handle(IntTools_Context) context = new IntTools_Context();
BOPTools_AlgoTools3D::PointNearEdge( TopoDS::Edge(exp.Current()), cf, p2d, p3d, context);
gp_Lin shot_line = projector.Shoot(p2d.X(), p2d.Y());
aSelFL.ResetResult();
aSelFL.SetLine( shot_line );
aTreeFL.Select(aSelFL);
std::vector<HLRFL_BndBoxTreeSelector::FaceParam> fp = aSelFL.GetRParams();
if (!fp.empty())
{
BRep_Builder().Add(aResCmp, cf);
if (theMode)
{
std::sort(fp.begin(), fp.end(), HLRBRep_ParComp);
OrigFaceToProjFace.Bind(cf, fp.front().myF);
}
}
}
//
return aResCmp;
}
TopoDS_Shape HLRBRep_HLRToShape::CompoundOfFaces(bool theMode,
TopTools_DataMapOfShapeShape& OrigFaceToProjFace)
{
//
TopTools_ListOfShape anOrigShapes;
const HLRBRep_SeqOfShapeBounds& aSeqOfShBnds = myAlgo->SeqOfShapeBounds();
for (int i=1; i<= aSeqOfShBnds.Size(); i++)
anOrigShapes.Append(aSeqOfShBnds(i).Shape()->OriginalShape());
//
TopoDS_Compound aTotalOSh;
BRep_Builder BB;
BB.MakeCompound(aTotalOSh);
TopoDS_Shape aSharpSh = InternalCompound(HLRBRep_Sharp, Standard_True, TopoDS_Shape(), Standard_False); //TODO check
if (!aSharpSh.IsNull())
BB.Add(aTotalOSh, aSharpSh);
TopoDS_Shape anOutLSh = InternalCompound(HLRBRep_OutLine, Standard_True, TopoDS_Shape(), Standard_False);
if (!anOutLSh.IsNull())
BB.Add(aTotalOSh, anOutLSh);
TopoDS_Shape aRg1Sh = InternalCompound(HLRBRep_Rg1Line, Standard_True, TopoDS_Shape(), Standard_False);
if (!aRg1Sh.IsNull())
BB.Add(aTotalOSh, aRg1Sh);
//
BRepLib::BuildCurves3d(aTotalOSh);
BRepLib::SameParameter(aTotalOSh, Precision::PConfusion(),Standard_False);
//
if( !FuseVE (aTotalOSh))
return TopoDS_Shape();
//
NCollection_DataMap<TopoDS_Edge, Bnd_Box2d, TopTools_ShapeMapHasher> theEdBnd2d;
NCollection_IndexedDataMap<TopoDS_Edge, BRepAdaptor_Curve2d, TopTools_ShapeMapHasher> anEdAd;
ProcessHVertices(aTotalOSh, anEdAd, theEdBnd2d);
//
TopoDS_Shape aRes = ProcessLoops(aTotalOSh, anEdAd, theEdBnd2d,
myAlgo->Projector(), anOrigShapes, theMode, OrigFaceToProjFace);
//
return aRes;
}

View File

@@ -25,6 +25,7 @@
#include <Standard_Integer.hxx>
#include <Standard_Boolean.hxx>
#include <HLRBRep_TypeOfResultingEdge.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
class HLRBRep_Algo;
class TopoDS_Shape;
class HLRBRep_Data;
@@ -131,6 +132,8 @@ public:
const Standard_Boolean visible,
const Standard_Boolean In3d);
TopoDS_Shape CompoundOfFaces (bool theMode,
TopTools_DataMapOfShapeShape& OrigFaceToProjFace);
protected:

View File

@@ -39,6 +39,7 @@
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <OSD_Parallel.hxx>
//=======================================================================
// Function : Load
@@ -173,7 +174,7 @@ HLRBRep_ShapeToHLR::Load(const Handle(HLRTopoBRep_OutLiner)& S,
void
HLRBRep_ShapeToHLR::ExploreFace(const Handle(HLRTopoBRep_OutLiner)& S,
const Handle(HLRBRep_Data)& DS,
Handle(HLRBRep_Data)& DS,
const TopTools_IndexedMapOfShape& FM,
const TopTools_IndexedMapOfShape& EM,
Standard_Integer& i,
@@ -193,7 +194,7 @@ HLRBRep_ShapeToHLR::ExploreFace(const Handle(HLRTopoBRep_OutLiner)& S,
for (Ex1.Init(theFace, TopAbs_WIRE); Ex1.More(); Ex1.Next())
nw++;
fd.Set (theFace, orient, closed, nw);
fd.Set (theFace, orient, closed, nw, Standard_False);
nw = 0;
for (Ex1.Init(theFace, TopAbs_WIRE); Ex1.More(); Ex1.Next()) {
@@ -234,15 +235,47 @@ HLRBRep_ShapeToHLR::ExploreFace(const Handle(HLRTopoBRep_OutLiner)& S,
//purpose :
//=======================================================================
class ParallelSurfInitFunctor
{
public:
ParallelSurfInitFunctor(HLRBRep_Array1OfFData& theFaceDataArr, const TopTools_IndexedMapOfShape& theFM)
: myFaceDataArr (theFaceDataArr), myFM (theFM)
{
}
void operator() (const Standard_Integer theIndex) const
{
const TopoDS_Face& aF = TopoDS::Face(myFM(theIndex));
HLRBRep_FaceData& fd = myFaceDataArr.ChangeValue(theIndex);
fd.Geometry().Surface( TopoDS::Face(aF.Oriented (TopAbs_FORWARD)));
}
private:
ParallelSurfInitFunctor( const ParallelSurfInitFunctor& );
ParallelSurfInitFunctor& operator =( ParallelSurfInitFunctor& );
private:
HLRBRep_Array1OfFData& myFaceDataArr;
const TopTools_IndexedMapOfShape& myFM;
};
void
HLRBRep_ShapeToHLR::ExploreShape (const Handle(HLRTopoBRep_OutLiner)& S,
const Handle(HLRBRep_Data)& DS,
Handle(HLRBRep_Data)& DS,
const TopTools_IndexedMapOfShape& FM,
const TopTools_IndexedMapOfShape& EM)
{
TopTools_MapOfShape ShapeMap;
TopExp_Explorer exshell, exface, exedge;
Standard_Integer i = 0;
Standard_Integer i = 1;
ParallelSurfInitFunctor aSurfFunctor(DS->FDataArray(), FM);
OSD_Parallel::For(1, FM.Extent() + 1, aSurfFunctor, Standard_False);
i = 0;
for (exshell.Init (S->OriginalShape(), TopAbs_SHELL);
exshell.More ();

View File

@@ -57,9 +57,9 @@ protected:
private:
Standard_EXPORT static void ExploreFace (const Handle(HLRTopoBRep_OutLiner)& S, const Handle(HLRBRep_Data)& DS, const TopTools_IndexedMapOfShape& FM, const TopTools_IndexedMapOfShape& EM, Standard_Integer& i, const TopoDS_Face& F, const Standard_Boolean closed);
Standard_EXPORT static void ExploreFace (const Handle(HLRTopoBRep_OutLiner)& S, Handle(HLRBRep_Data)& DS, const TopTools_IndexedMapOfShape& FM, const TopTools_IndexedMapOfShape& EM, Standard_Integer& i, const TopoDS_Face& F, const Standard_Boolean closed);
Standard_EXPORT static void ExploreShape (const Handle(HLRTopoBRep_OutLiner)& S, const Handle(HLRBRep_Data)& DS, const TopTools_IndexedMapOfShape& FM, const TopTools_IndexedMapOfShape& EM);
Standard_EXPORT static void ExploreShape (const Handle(HLRTopoBRep_OutLiner)& S, Handle(HLRBRep_Data)& DS, const TopTools_IndexedMapOfShape& FM, const TopTools_IndexedMapOfShape& EM);

View File

@@ -62,14 +62,109 @@
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <HLRAlgo_Projector.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <NCollection_Handle.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <OSD_Parallel.hxx>
#include <math_FunctionSetRoot.hxx>
#include <Adaptor3d_HSurfaceTool.hxx>
#include <NCollection_List.hxx>
struct ContourSurfInfo
{
ContourSurfInfo() : myDomain(NULL), mySurface(NULL)
{};
ContourSurfInfo(NCollection_Handle<Contap_Contour> theHFO,
const Handle(BRepTopAdaptor_TopolTool)& theDomain,
const Handle(Adaptor3d_HSurface) theSurface) :
myHFO(theHFO), myDomain (theDomain.get()), mySurface (theSurface.get())
{};
ContourSurfInfo& operator=( const ContourSurfInfo& otherSurfInfo)
{
myHFO = otherSurfInfo.myHFO;
myDomain = otherSurfInfo.myDomain;
mySurface = otherSurfInfo.mySurface;
return *this;
};
NCollection_Handle<Contap_Contour> myHFO;
const BRepTopAdaptor_TopolTool* myDomain;
const Adaptor3d_HSurface* mySurface;
};
struct BRTInfo
{
BRTInfo()
{};
BRTInfo(BRepTopAdaptor_Tool* thepBRT, ContourSurfInfo* theCSI, const TopoDS_Face& theF )
: mypBRT (thepBRT), myCSI (theCSI), myF (theF)
{};
BRepTopAdaptor_Tool* mypBRT;
ContourSurfInfo* myCSI;
TopoDS_Face myF;
};
class ParallelContourFunctor
{
public:
ParallelContourFunctor(NCollection_Array1<ContourSurfInfo>& theContourSurfInfo)
: myContourSurfInfo (theContourSurfInfo)
{
}
void operator() (const Standard_Integer theIndex) const
{
ContourSurfInfo& aCSInfo = myContourSurfInfo(theIndex);
aCSInfo.myHFO->Perform(aCSInfo.mySurface, aCSInfo.myDomain);
}
private:
ParallelContourFunctor( const ParallelContourFunctor& );
ParallelContourFunctor& operator =( ParallelContourFunctor& );
private:
NCollection_Array1<ContourSurfInfo>& myContourSurfInfo;
};
class ParallelBRTInitFunctor
{
public:
ParallelBRTInitFunctor(NCollection_Array1<BRTInfo>& theBRTInfo)
: myBRTInfo (theBRTInfo)
{
}
void operator() (const Standard_Integer theIndex) const
{
BRTInfo& BI = myBRTInfo(theIndex);
BI.mypBRT->Init(BI.myF,Precision::PConfusion());
BI.myCSI->myDomain = BI.mypBRT->GetTopolTool().get();
BI.myCSI->mySurface = BI.mypBRT->GetSurface().get();
}
private:
ParallelBRTInitFunctor( const ParallelBRTInitFunctor& );
ParallelBRTInitFunctor& operator =( ParallelBRTInitFunctor& );
private:
NCollection_Array1<BRTInfo>& myBRTInfo;
};
//=======================================================================
//function : Insert
//purpose : explore the faces and insert them
//=======================================================================
void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
Contap_Contour& FO,
const HLRAlgo_Projector& P,
const gp_Vec& Vecz,
HLRTopoBRep_Data& DS,
BRepTopAdaptor_MapOfShapeTool& MST,
const Standard_Integer nbIso)
@@ -78,38 +173,135 @@ void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
TopExp_Explorer ex(S,TopAbs_FACE);
DS.Clear();
Standard_Boolean withPCurve = Standard_True; // instead of nbIso != 0;
Standard_Integer f = 0;
while (ex.More()) {
if (ShapeMap.Add(ex.Current())) {
f++;
gp_Pnt Eye;
gp_Dir DirZ;
if (P.Perspective ())
Eye.SetXYZ (P.Focus ()*Vecz.XYZ ());
else
DirZ = Vecz;
NCollection_List<ContourSurfInfo> ContourSurfInfoList;
NCollection_List<BRTInfo> nonInitBRTs;
while (ex.More())
{
if (ShapeMap.Add(ex.Current()))
{
TopoDS_Face S1 = TopoDS::Face(ex.Current());
S1.Orientation(TopAbs_FORWARD);
Handle(BRepTopAdaptor_TopolTool) Domain;
Handle(Adaptor3d_HSurface) Surface;
if(MST.IsBound(S1)) {
BRepTopAdaptor_Tool& BRT = MST.ChangeFind(S1);
Domain = BRT.GetTopolTool();
Surface = BRT.GetSurface();
//
NCollection_Handle<Contap_Contour> HFO = new Contap_Contour();
if (P.Perspective ())
HFO->Init(Eye);
else
HFO->Init(DirZ);
//
BRepTopAdaptor_Tool* pBRT = MST.ChangeSeek(S1);
if(pBRT)
{
ContourSurfInfo CSInfo(HFO, pBRT->GetTopolTool(), pBRT->GetSurface());
ContourSurfInfoList.Append(CSInfo);
}
else {
BRepTopAdaptor_Tool BRT(S1,Precision::PConfusion());
MST.Bind(S1,BRT);
Domain = BRT.GetTopolTool();
Surface = BRT.GetSurface();
else
{
pBRT = MST.Bound(S1,BRepTopAdaptor_Tool());
BRTInfo& brtI = nonInitBRTs.Append(BRTInfo());
brtI.mypBRT = pBRT;
brtI.myCSI = &ContourSurfInfoList.Append(ContourSurfInfo(HFO, NULL, NULL));
brtI.myF = S1;
}
FO.Perform(Surface, Domain);
if (FO.IsDone()) {
if (!FO.IsEmpty())
InsertFace(f,S1,FO,DS,withPCurve);
}
if (nbIso != 0) HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
}
ex.Next();
}
//
NCollection_List<BRTInfo>::Iterator itBRTIt(nonInitBRTs);
NCollection_Array1<BRTInfo> nonInitBRTArr(1, nonInitBRTs.Extent());
Standard_Integer f = 1;
for (;itBRTIt.More();itBRTIt.Next(), f++)
nonInitBRTArr(f) = itBRTIt.Value();
ParallelBRTInitFunctor aBRTFunctor(nonInitBRTArr);
OSD_Parallel::For(nonInitBRTArr.Lower(), nonInitBRTArr.Upper() + 1, aBRTFunctor, Standard_False);
//
NCollection_List<ContourSurfInfo>::Iterator itCS(ContourSurfInfoList);
int nbC = ContourSurfInfoList.Extent();
f = 1;
NCollection_Array1<ContourSurfInfo> aContourSurfInfoArray(1, nbC);
for (;itCS.More();itCS.Next(), f++)
aContourSurfInfoArray(f) = itCS.Value();
//
ParallelContourFunctor aContourFunctor(aContourSurfInfoArray);
OSD_Parallel::For(aContourSurfInfoArray.Lower(), aContourSurfInfoArray.Upper() + 1, aContourFunctor, Standard_False);
//
for (f = aContourSurfInfoArray.Lower(); f <= aContourSurfInfoArray.Upper(); f++)
{
ContourSurfInfo& CSInfo = aContourSurfInfoArray(f);
Handle(BRepAdaptor_HSurface) BrepSurf = Handle(BRepAdaptor_HSurface)::DownCast(CSInfo.mySurface);
const TopoDS_Face& S1 = BrepSurf->ChangeSurface().Face();
if (CSInfo.myHFO->IsDone())
if (!CSInfo.myHFO->IsEmpty())
InsertFace(f,S1,*CSInfo.myHFO, CSInfo.myDomain, DS,withPCurve);
if (nbIso != 0)
HLRTopoBRep_FaceIsoLiner::Perform(f,S1,DS,nbIso);
}
//
ProcessEdges(DS);
}
static void GetSurfInfo(const Handle(Adaptor3d_HSurface)& Surf, math_Vector& tol,
math_Vector& inf, math_Vector& sup)
{
tol(1) = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
tol(2) = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
inf(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
inf(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
sup(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
sup(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
}
//=======================================================================
//function : ClarifyPoint
//purpose : p2d - point to clarify, p2d corresponds to the clarifying 2d point on surface Surf
//=======================================================================
static bool ClarifyPoint(math_FunctionSetRoot& rsnld, Contap_SurfFunction& SFunc,
const BRepTopAdaptor_TopolTool* Domain, math_Vector& inf, math_Vector& sup,
gp_Pnt2d& P2d, gp_Pnt& p3d)
{
math_Vector StartP(1,2);
StartP.Value(1) = P2d.X() ;
StartP.Value(2) = P2d.Y();
rsnld.Perform(SFunc,StartP,inf,sup);
if (rsnld.IsDone())
{
math_Vector Sol(1,2);
math_Vector F(1,1);
rsnld.Root(Sol);
SFunc.Value(Sol,F);
if (Abs(F(1)) <= SFunc.Tolerance())
{
P2d.SetCoord(Sol(1), Sol(2));
TopAbs_State state = const_cast<BRepTopAdaptor_TopolTool*>(Domain)
->Classify(P2d,Precision::PConfusion());
if (state == TopAbs_IN || state == TopAbs_ON)
{
const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
p3d = Adaptor3d_HSurfaceTool::Value(Surf,P2d.X(),P2d.Y());
return true;
}
}
}
return false;
}
//=======================================================================
//function : InsertFace
//purpose : private, insert the outlines of a face
@@ -117,7 +309,7 @@ void HLRTopoBRep_DSFiller::Insert (const TopoDS_Shape& S,
void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
const TopoDS_Face& F,
Contap_Contour& FO,
Contap_Contour& FO, const BRepTopAdaptor_TopolTool* Domain,
HLRTopoBRep_Data& DS,
const Standard_Boolean withPCurve)
{
@@ -339,7 +531,8 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
Maxx=Maxy=Maxz=Maxu=Maxv=-RealLast();
Minx=Miny=Minz=Minu=Minv=RealLast();
for(Standard_Integer i=1;i<=nbp;i++) {
for(Standard_Integer i=1;i<=nbp;i++)
{
knots.SetValue(i,(Standard_Real)i);
mults.SetValue(i,1);
const gp_Pnt& P= Line.Point(i+ipF-1).Value();
@@ -352,29 +545,30 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
Points.SetValue(i,P);
}
mults(1)=mults(nbp)=2;
Handle(Geom_BSplineCurve) AppC;
Handle(Geom2d_BSplineCurve) AppC2d;
AppC = new Geom_BSplineCurve(Points,knots,mults,1);
//Handle(Geom_BSplineCurve) AppC;
//Handle(Geom2d_BSplineCurve) AppC2d;
//AppC = new Geom_BSplineCurve(Points,knots,mults,1);
if(withPCurve) {
TColgp_Array1OfPnt2d Points2d(1,nbp);
for(Standard_Integer i=1;i<=nbp;i++) {
Standard_Real u,v;
Line.Point(i+ipF-1).ParametersOnS2(u,v);
if(u<Minu) Minu=u;
if(v<Minv) Minv=v;
if(u>Maxu) Maxu=u;
if(v>Maxv) Maxv=v;
Points2d.SetValue(i,gp_Pnt2d(u,v));
}
AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
TColgp_Array1OfPnt2d Points2d(1,nbp);
for(Standard_Integer i=1;i<=nbp;i++)
{
Standard_Real u,v;
Line.Point(i+ipF-1).ParametersOnS2(u,v);
if(u<Minu) Minu=u;
if(v<Minv) Minv=v;
if(u>Maxu) Maxu=u;
if(v>Maxv) Maxv=v;
Points2d.SetValue(i,gp_Pnt2d(u,v));
}
//AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
first = 1;
last = nbp;
Handle(BRepApprox_ApproxLine) AppLine;
//Handle(BRepApprox_ApproxLine) AppLine;
Handle(Geom2d_BSplineCurve) CNull;
AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
//AppLine = new BRepApprox_ApproxLine(AppC,AppC2d,CNull);
Standard_Integer dmin=4,dmax=8,niter=0;
Standard_Boolean tg= Standard_False;
@@ -390,13 +584,139 @@ void HLRTopoBRep_DSFiller::InsertFace (const Standard_Integer /*FI*/,
TOL3d=TOL*Maxx; if(TOL3d<1e-12) TOL3d=1e-12; else if(TOL3d>0.1) TOL3d=0.1;
TOL2d=TOL*Maxu; if(TOL2d<1e-12) TOL2d=1e-12; else if(TOL2d>0.1) TOL2d=0.1;
Contap_SurfFunction& SFunc = FO.SurfaceFunction();
const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
double cmax = 2.0;
double c = 100;
int newsize;
NCollection_List<gp_Pnt2d> lp2d;
NCollection_List<gp_Pnt> lp;
lp2d.Append(Points2d.First());
lp.Append(Points.First());
for (int jj=2; jj < Points.Size(); jj++ )
{
gp_Pnt curPnt = Points(jj);
gp_Pnt2d curPnt2d = Points2d(jj);
double d3_1 = lp.Last().Distance(curPnt);
double d3_2 = curPnt.Distance(Points(jj+1));
double d1 = lp2d.Last().Distance(Points2d(jj));
double d2 = Points2d(jj).Distance(Points2d(jj+1));
double x0 = curPnt2d.X();
double y0 = curPnt2d.Y();
double coeff = d3_1/d3_2;
c = 1.4;
if (coeff > cmax)
{
//left is wider
double t = 1;
double x1 = lp2d.Last().X();
double y1 = lp2d.Last().Y();
NCollection_List<gp_Pnt2d> dp;
NCollection_List<gp_Pnt> dp3d;
math_Vector tol(1,2), inf(1,2), sup(1,2);
GetSurfInfo(Surf, tol, inf, sup);
math_FunctionSetRoot rsnld(SFunc,tol,50);
for (;;)
{
t = 1 - d2/d1*c;
if (t <= 0)
break;
gp_Pnt2d pnt;
double Xt = x0 + (x1-x0)*t;
double Yt = y0 + (y1-y0)*t;
c=c*c;
gp_Pnt2d draft2d(Xt, Yt);
gp_Pnt draft3d;
//
if (ClarifyPoint(rsnld, SFunc, Domain, inf, sup, draft2d, draft3d))
{
lp2d.Append(dp);
lp.Append(dp3d);
}
}
//
lp2d.Append(curPnt2d);
lp.Append(curPnt);
}
else if (1/coeff > cmax )
{
//right is wider
double t = 0;
lp2d.Append(curPnt2d);
lp.Append(curPnt);
double x1 = Points2d(jj+1).X();
double y1 = Points2d(jj+1).Y();
math_Vector tol(1,2), inf(1,2), sup(1,2);
GetSurfInfo(Surf, tol, inf, sup);
math_FunctionSetRoot rsnld(SFunc,tol,50);
for (;;)
{
t = d1/d2*c;
if (t >= 1)
break;
gp_Pnt2d pnt;
double Xt = x0 + (x1-x0)*t;
double Yt = y0 + (y1-y0)*t;
c=c*c;
gp_Pnt2d draft2d(Xt, Yt);
gp_Pnt draft3d;
//
if (ClarifyPoint(rsnld, SFunc, Domain, inf, sup, draft2d, draft3d))
{
lp.Append(draft3d);
lp2d.Append(draft2d);
}
}
}
else
{
lp2d.Append(curPnt2d);
lp.Append(curPnt);
}
}
lp2d.Append(Points2d.Last());
lp.Append(Points.Last());
//
newsize = lp.Size();
TColgp_Array1OfPnt2d newPoints2dA(1,newsize);
TColgp_Array1OfPnt newPoints3dA(1,newsize);
TColStd_Array1OfReal nknots(1,newsize);
TColStd_Array1OfInteger nmults(1,newsize);
NCollection_List<gp_Pnt>::Iterator itl(lp);
NCollection_List<gp_Pnt2d>::Iterator itl2(lp2d);
for (int jj = 1;itl.More(), itl2.More();itl.Next(), itl2.Next(), jj++)
{
nknots.SetValue(jj,(Standard_Real)jj);
nmults.SetValue(jj,1);
newPoints2dA.SetValue(jj, itl2.Value());
newPoints3dA.SetValue(jj, itl.Value());
}
nmults(1)=nmults(newsize)=2;
Handle_BRepApprox_ApproxLine nAppLine ;
Handle(Geom_BSplineCurve) nAppC =
new Geom_BSplineCurve(newPoints3dA,nknots,nmults,1);
Handle(Geom2d_BSplineCurve) nAppC2d=
new Geom2d_BSplineCurve(newPoints2dA,nknots,nmults,1);
nAppLine = new BRepApprox_ApproxLine(nAppC,nAppC2d,CNull);
//AppC2d = new Geom2d_BSplineCurve(Points2d,knots,mults,1);
//-- cout<<"\nHLRTopoBRep_DSFiller : nbp="<<nbp<<" Tol3d="<<TOL3d<<" Tol2d="<<TOL2d<<endl;
Approx.SetParameters(TOL3d, TOL2d, dmin, dmax, niter, 30, tg);
Approx.Perform(AppLine,Standard_True,Standard_True,Standard_False,1,nbp);
Approx.Perform(nAppLine,Standard_True,Standard_True,Standard_False,1,newsize/*nbp*/);
if (!Approx.IsDone()) {
C = AppC;
C2d=AppC2d;
C = nAppC;
C2d=nAppC2d;
first = 1;
last = nbp;
}

View File

@@ -32,6 +32,7 @@ class TopoDS_Face;
class TopoDS_Vertex;
class Contap_Point;
class TopoDS_Edge;
class HLRAlgo_Projector;
//! Provides methods to fill a HLRTopoBRep_Data.
@@ -44,7 +45,7 @@ public:
//! Stores in <DS> the outlines of <S> using the current
//! outliner and stores the isolines in <DS> using a Hatcher.
Standard_EXPORT static void Insert (const TopoDS_Shape& S, Contap_Contour& FO, HLRTopoBRep_Data& DS, BRepTopAdaptor_MapOfShapeTool& MST, const Standard_Integer nbIso);
Standard_EXPORT static void Insert (const TopoDS_Shape& S,const HLRAlgo_Projector& P, const gp_Vec& Vecz, HLRTopoBRep_Data& DS, BRepTopAdaptor_MapOfShapeTool& MST, const Standard_Integer nbIso);
@@ -60,7 +61,8 @@ private:
//! Stores in <DS> the outlines of <F> using the current
//! outliner.
Standard_EXPORT static void InsertFace (const Standard_Integer FI, const TopoDS_Face& F, Contap_Contour& FO, HLRTopoBRep_Data& DS, const Standard_Boolean withPCurve);
Standard_EXPORT static void InsertFace (const Standard_Integer FI, const TopoDS_Face& F, Contap_Contour& FO,
const BRepTopAdaptor_TopolTool* Domain, HLRTopoBRep_Data& DS, const Standard_Boolean withPCurve);
//! Make a vertex from an intersection point <P>and
//! store it in the data structure <DS>.

View File

@@ -82,17 +82,7 @@ void HLRTopoBRep_OutLiner::Fill(const HLRAlgo_Projector& P,
gp_Trsf Tr (P.Transformation ());
Tr.Invert ();
Vecz.Transform (Tr);
Contap_Contour FO;
if (P.Perspective ()) {
gp_Pnt Eye;
Eye.SetXYZ (P.Focus ()*Vecz.XYZ ());
FO.Init(Eye);
}
else {
gp_Dir DirZ(Vecz);
FO.Init(DirZ);
}
HLRTopoBRep_DSFiller::Insert(myOriginalShape,FO,myDS,MST,nbIso);
HLRTopoBRep_DSFiller::Insert(myOriginalShape,P,Vecz,myDS,MST,nbIso);
BuildShape(MST);
}
}

View File

@@ -1584,6 +1584,7 @@ static Standard_Integer OCC26930(Draw_Interpretor& theDI,
//function : OCC27341
//purpose : check exact HLR algorighm's work
//=======================================================================
#include <OSD_Timer.hxx>
static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const char** a)
{
if (n != 4)
@@ -1643,7 +1644,11 @@ static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const
anOrigin.X(), anOrigin.Y(), anOrigin.Z(),
aDX.X(), aDX.Y(), aDX.Z());
OSD_Timer aTimer;
aTimer.Start();
Reflector.Perform();
aTimer.Stop();
aTimer.Show();
TopoDS_Compound Result;
BRep_Builder BB;
@@ -1664,6 +1669,80 @@ static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const
return 0;
}
//=======================================================================
//function : OCC28991
//purpose :
//=======================================================================
static Standard_Integer OCC28991 (Draw_Interpretor& , Standard_Integer n, const char** a)
{
if (n != 4)
{
cout << "Use: OCC28991 res shape axo/top/bottom/front/back/left/right" << endl;
return 1;
}
TopoDS_Shape aShape = DBRep::Get(a[2]);
if (aShape.IsNull())
return 1;
gp_Pnt anOrigin(0.,0.,0.);
gp_Dir aNormal(0.57735026918962573, -0.57735026918962573, 0.57735026918962573);
gp_Ax2 anAxes(anOrigin, aNormal);
gp_Dir aDX = anAxes.XDirection();
HLRAppli_ReflectLines Reflector(aShape);
if (strcmp(a[3],"axo") == 0)
{
aNormal.SetCoord(0.57735026918962573, -0.57735026918962573, 0.57735026918962573);
aDX.SetCoord(-0.40824829046386307, 0.40824829046386307, 0.81649658092772615);
}
else if (strcmp(a[3],"top") == 0)
{
aNormal.SetCoord(0,0,1);
aDX.SetCoord(0,1,0);
}
else if (strcmp(a[3],"bottom") == 0)
{
aNormal.SetCoord(0,0,-1);
aDX.SetCoord(0,-1,0);
}
else if (strcmp(a[3],"front") == 0)
{
aNormal.SetCoord(0,-1,0);
aDX.SetCoord(0,0,1);
}
else if (strcmp(a[3],"back") == 0)
{
aNormal.SetCoord(0,1,0);
aDX.SetCoord(0,0,1);
}
else if (strcmp(a[3],"left") == 0)
{
aNormal.SetCoord(-1,0,0);
aDX.SetCoord(0,0,1);
}
else if (strcmp(a[3],"right") == 0)
{
aNormal.SetCoord(1,0,0);
aDX.SetCoord(0,0,1);
}
Reflector.SetAxes(aNormal.X(), aNormal.Y(), aNormal.Z(),
anOrigin.X(), anOrigin.Y(), anOrigin.Z(),
aDX.X(), aDX.Y(), aDX.Z());
Reflector.Perform();
TopTools_DataMapOfShapeShape aDummy;
TopoDS_Shape aFaces = Reflector.GetCompoundOfFaces(true, aDummy);
DBRep::Set(a[1], aFaces);
return 0;
}
//=======================================================================
//function : OCC27466
//purpose :
@@ -2447,6 +2526,9 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
theCommands.Add("OCC27341",
"OCC27341 res shape axo/top/bottom/front/back/left/right",
__FILE__, OCC27341, group);
theCommands.Add("OCC28991",
"OCC289911 res shape axo/top/bottom/front/back/left/right",
__FILE__, OCC28991, group);
theCommands.Add ("OCC26747_1", "OCC26747_1 result", __FILE__, OCC26747_1, group);
theCommands.Add ("OCC26747_2", "OCC26747_2 result", __FILE__, OCC26747_2, group);
theCommands.Add ("OCC26747_3", "OCC26747_3 result", __FILE__, OCC26747_3, group);

View File

@@ -6,3 +6,4 @@ TKG2d
TKG3d
TKGeomAlgo
TKTopAlgo
TKBO