1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-01 17:36:21 +03:00

0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection algorithm

The usage of *BRepAlgo_Section* has been replaced with the usage of *BRepAlgoAPI_Section* in *BRepProj_Projection* algorithm.

The TODO statements have been removed from the failing test case in the "prj" grid as they are working correctly now.

The following changes have been made to improve the performance *BRepAlgoAPI_Section*:
1. Revision of the *IntPolyh_Intersection* class to avoid repeated calculation of the deflection of the same triangulation.
2. Small revision of the Edge/Face intersection algorithm to perform Extrema computation on the whole intersection range of the edge instead of discrete ranges.
3. Implementation of the extrema computation for the Circle and Sphere.
4. Correct computation of the parameter of the point on the Circle.
This commit is contained in:
emv 2017-12-26 14:28:27 +03:00 committed by apn
parent 95f688263d
commit 03cca6f742
50 changed files with 2340 additions and 1978 deletions

View File

@ -1529,3 +1529,6 @@ The public method *BuildSection()* in the class *BOPAlgo_Section* has became pro
The method BRepAdaptor_CompCurve::SetPeriodic has been eliminated.
Since new version, the method BRepAdaptor_CompCurve::IsPeriodic() will always return FALSE. Earlier, it could return TRUE in case if the wire contained only one edge based on periodic curve.
@subsection upgrade_730_removed Removed features
* The methods *SetDeflection*, *SetEpsilonT*, *SetDiscretize* of the class *IntTools_EdgeFace* have been removed as excessive.

View File

@ -167,9 +167,9 @@ void BOPAlgo_PaveFiller::PerformEF()
Standard_Boolean bV[2], bIsPBSplittable;
Standard_Boolean bV1, bV2, bExpressCompute;
Standard_Integer nV1, nV2;
Standard_Integer aDiscretize, i, aNbCPrts, iX, nV[2];
Standard_Integer i, aNbCPrts, iX, nV[2];
Standard_Integer aNbEdgeFace, k;
Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2;
Handle(NCollection_BaseAllocator) aAllocator;
TopAbs_ShapeEnum aType;
BOPDS_ListIteratorOfListOfPaveBlock aIt;
@ -183,9 +183,6 @@ void BOPAlgo_PaveFiller::PerformEF()
BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
//
aDiscretize=35;
aDeflection=0.01;
//
BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
aEFs.SetIncrement(iSize);
//
@ -242,8 +239,6 @@ void BOPAlgo_PaveFiller::PerformEF()
aEdgeFace.SetEdge (aE);
aEdgeFace.SetFace (aF);
aEdgeFace.SetFuzzyValue(myFuzzyValue);
aEdgeFace.SetDiscretize (aDiscretize);
aEdgeFace.SetDeflection (aDeflection);
aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
//
IntTools_Range aSR(aTS1, aTS2);

View File

@ -1,55 +0,0 @@
// Created on: 2002-03-04
// Created by: Michael KLOKOV
// Copyright (c) 2002-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 <BOPAlgo_SectionAttribute.hxx>
//=======================================================================
// function: BOPAlgo_SectionAttribute
// purpose:
//=======================================================================
BOPAlgo_SectionAttribute::BOPAlgo_SectionAttribute(const Standard_Boolean Aproximation,
const Standard_Boolean PCurveOnS1,
const Standard_Boolean PCurveOnS2)
{
myApproximation = Aproximation;
myPCurve1 = PCurveOnS1;
myPCurve2 = PCurveOnS2;
}
//=======================================================================
// function: Approximation
// purpose:
//=======================================================================
void BOPAlgo_SectionAttribute::Approximation(const Standard_Boolean theFlag)
{
myApproximation = theFlag;
}
//=======================================================================
// function: PCurveOnS1
// purpose:
//=======================================================================
void BOPAlgo_SectionAttribute::PCurveOnS1(const Standard_Boolean theFlag)
{
myPCurve1 = theFlag;
}
//=======================================================================
// function: PCurveOnS2
// purpose:
//=======================================================================
void BOPAlgo_SectionAttribute::PCurveOnS2(const Standard_Boolean theFlag)
{
myPCurve2 = theFlag;
}

View File

@ -16,75 +16,72 @@
#ifndef _BOPAlgo_SectionAttribute_HeaderFile
#define _BOPAlgo_SectionAttribute_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Boolean.hxx>
//! Class is a container of three flags used
//! Class is a container of the flags used
//! by intersection algorithm
class BOPAlgo_SectionAttribute
class BOPAlgo_SectionAttribute
{
public:
DEFINE_STANDARD_ALLOC
//! Default constructor
BOPAlgo_SectionAttribute()
: myApproximation(Standard_True),
myPCurve1(Standard_True),
myPCurve2(Standard_True) {}
//! Constructor
BOPAlgo_SectionAttribute(const Standard_Boolean theAproximation,
const Standard_Boolean thePCurveOnS1,
const Standard_Boolean thePCurveOnS2)
: myApproximation(theAproximation),
myPCurve1(thePCurveOnS1),
myPCurve2(thePCurveOnS2) {}
//! Initializes me by flags
Standard_EXPORT BOPAlgo_SectionAttribute(const Standard_Boolean Aproximation = Standard_True, const Standard_Boolean PCurveOnS1 = Standard_True, const Standard_Boolean PCurveOnS2 = Standard_True);
//! Sets the Approximation flag
void Approximation(const Standard_Boolean theApprox)
{
myApproximation = theApprox;
}
//! Modifier
Standard_EXPORT void Approximation (const Standard_Boolean theFlag);
//! Sets the PCurveOnS1 flag
void PCurveOnS1(const Standard_Boolean thePCurveOnS1)
{
myPCurve1 = thePCurveOnS1;
}
//! Modifier
Standard_EXPORT void PCurveOnS1 (const Standard_Boolean theFlag);
//! Modifier
Standard_EXPORT void PCurveOnS2 (const Standard_Boolean theFlag);
//! Selector
Standard_Boolean Approximation() const;
//! Selector
Standard_Boolean PCurveOnS1() const;
//! Selector
Standard_Boolean PCurveOnS2() const;
//! Sets the PCurveOnS2 flag
void PCurveOnS2(const Standard_Boolean thePCurveOnS2)
{
myPCurve2 = thePCurveOnS2;
}
//! Returns the Approximation flag
Standard_Boolean Approximation() const
{
return myApproximation;
}
//! Returns the PCurveOnS1 flag
Standard_Boolean PCurveOnS1() const
{
return myPCurve1;
}
//! Returns the PCurveOnS2 flag
Standard_Boolean PCurveOnS2() const
{
return myPCurve2;
}
protected:
private:
Standard_Boolean myApproximation;
Standard_Boolean myPCurve1;
Standard_Boolean myPCurve2;
};
#include <BOPAlgo_SectionAttribute.lxx>
#endif // _BOPAlgo_SectionAttribute_HeaderFile

View File

@ -1,41 +0,0 @@
// Created on: 2002-03-04
// Created by: Michael KLOKOV
// Copyright (c) 2002-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.
//=======================================================================
// function:Approximation
// purpose:
//=======================================================================
inline Standard_Boolean BOPAlgo_SectionAttribute::Approximation() const
{
return myApproximation;
}
//=======================================================================
// function:PCurveOnS1
// purpose:
//=======================================================================
inline Standard_Boolean BOPAlgo_SectionAttribute::PCurveOnS1() const
{
return myPCurve1;
}
//=======================================================================
// function:PCurveOnS2
// purpose:
//=======================================================================
inline Standard_Boolean BOPAlgo_SectionAttribute::PCurveOnS2() const
{
return myPCurve2;
}

View File

@ -55,9 +55,7 @@ BOPAlgo_PSection.hxx
BOPAlgo_PWireEdgeSet.hxx
BOPAlgo_Section.cxx
BOPAlgo_Section.hxx
BOPAlgo_SectionAttribute.cxx
BOPAlgo_SectionAttribute.hxx
BOPAlgo_SectionAttribute.lxx
BOPAlgo_ShellSplitter.cxx
BOPAlgo_ShellSplitter.hxx
BOPAlgo_Tools.cxx

View File

@ -101,7 +101,10 @@ static Standard_Integer mkvolume (Draw_Interpretor&, Standard_Integer, const c
theCommands.Add("bfuse" , "use bfuse r s1 s2" , __FILE__,bfuse, g);
theCommands.Add("bcut" , "use bcut r s1 s2" , __FILE__,bcut, g);
theCommands.Add("btuc" , "use btuc r s1 s2" , __FILE__,btuc, g);
theCommands.Add("bsection", "use bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na]",
theCommands.Add("bsection", "use bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na]"
"Builds section between shapes. Options:\n"
"-n2d/-n2d1/-n2d2 - disable the PCurve construction;\n"
"-na - disables the approximation of the section curves.\n",
__FILE__, bsection, g);
//
theCommands.Add("bopcurves", "use bopcurves F1 F2 [-2d/-2d1/-2d2] "

View File

@ -17,24 +17,22 @@
// modified by Michael KLOKOV Wed Mar 6 15:01:25 2002
// modified by Eugeny MALTCHIKOV Wed Jul 04 11:13:01 2012
#include <BOPAlgo_BOP.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_Section.hxx>
#include <BOPDS_DS.hxx>
#include <BRep_Tool.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPDS_DS.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
#include <gp_Pln.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
//
static
@ -176,11 +174,9 @@ BRepAlgoAPI_Section::~BRepAlgoAPI_Section()
void BRepAlgoAPI_Section::Init(const Standard_Boolean bFlag)
{
myOperation=BOPAlgo_SECTION;
myParametersChanged = Standard_False;
myApprox = Standard_False;
myComputePCurve1 = Standard_False;
myComputePCurve2 = Standard_False;
myParametersChanged = Standard_True;
//
if (bFlag) {
Build();
@ -194,7 +190,6 @@ void BRepAlgoAPI_Section::Init1(const TopoDS_Shape& S1)
{
myArguments.Clear();
myArguments.Append(S1);
myParametersChanged = Standard_True;
}
//=======================================================================
//function : Init1
@ -220,7 +215,6 @@ void BRepAlgoAPI_Section::Init2(const TopoDS_Shape& S2)
{
myTools.Clear();
myTools.Append(S2);
myParametersChanged = Standard_True;
}
//=======================================================================
//function : Init2
@ -244,10 +238,7 @@ void BRepAlgoAPI_Section::Init2(const Handle(Geom_Surface)& Sf)
//=======================================================================
void BRepAlgoAPI_Section::Approximation(const Standard_Boolean B)
{
if(myApprox != B) {
myApprox = B;
myParametersChanged = Standard_True;
}
myApprox = B;
}
//=======================================================================
//function : ComputePCurveOn1
@ -255,10 +246,7 @@ void BRepAlgoAPI_Section::Approximation(const Standard_Boolean B)
//=======================================================================
void BRepAlgoAPI_Section::ComputePCurveOn1(const Standard_Boolean B)
{
if(myComputePCurve1 != B) {
myComputePCurve1 = B;
myParametersChanged = Standard_True;
}
myComputePCurve1 = B;
}
//=======================================================================
//function : ComputePCurveOn2
@ -266,10 +254,7 @@ void BRepAlgoAPI_Section::ComputePCurveOn1(const Standard_Boolean B)
//=======================================================================
void BRepAlgoAPI_Section::ComputePCurveOn2(const Standard_Boolean B)
{
if(myComputePCurve2 != B) {
myComputePCurve2 = B;
myParametersChanged = Standard_True;
}
myComputePCurve2 = B;
}
//=======================================================================
//function : SetAttributes
@ -277,9 +262,9 @@ void BRepAlgoAPI_Section::ComputePCurveOn2(const Standard_Boolean B)
//=======================================================================
void BRepAlgoAPI_Section::SetAttributes()
{
BOPAlgo_SectionAttribute theSecAttr(myApprox,
myComputePCurve1,
myComputePCurve2);
BOPAlgo_SectionAttribute theSecAttr(myApprox,
myComputePCurve1,
myComputePCurve2);
myDSFiller->SetSectionAttribute(theSecAttr);
}
//=======================================================================

View File

@ -193,8 +193,6 @@ Standard_EXPORT virtual ~BRepAlgoAPI_Section();
Standard_EXPORT Standard_Boolean HasAncestorFaceOn2 (const TopoDS_Shape& E, TopoDS_Shape& F) const;
protected:
@ -203,24 +201,12 @@ protected:
Standard_EXPORT virtual void SetAttributes() Standard_OVERRIDE;
private:
Standard_Boolean myParametersChanged;
Standard_Boolean myApprox;
Standard_Boolean myComputePCurve1;
Standard_Boolean myComputePCurve2;
};
#endif // _BRepAlgoAPI_Section_HeaderFile

View File

@ -16,7 +16,7 @@
#include <Bnd_Box.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAlgo_Section.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepBndLib.hxx>
#include <BRepFill_Generator.hxx>
#include <BRepLib_MakeEdge.hxx>
@ -125,15 +125,17 @@ void BRepProj_Projection::BuildSection (const TopoDS_Shape& theShape,
if ( aShape.IsNull() )
throw Standard_ConstructionError(__FILE__": target shape has no faces");
// build section computing pcurves on the shape
// BRepAlgoAPI_Section aSectionTool (aShape, theTool, Standard_False);
BRepAlgo_Section aSectionTool (aShape, theTool, Standard_False);
aSectionTool.Approximation (Standard_True);
aSectionTool.ComputePCurveOn1 (Standard_True);
// build section computing p-curves on both shapes to get higher precision
BRepAlgoAPI_Section aSectionTool(aShape, theTool, Standard_False);
aSectionTool.Approximation(Standard_True);
aSectionTool.ComputePCurveOn1(Standard_True);
aSectionTool.ComputePCurveOn2(Standard_True);
// Use Oriented Bounding Boxes inside Booleans to speed up calculation of the section
aSectionTool.SetUseOBB(Standard_True);
aSectionTool.Build();
// check for successful work of the section tool
if (! aSectionTool.IsDone())
if (!aSectionTool.IsDone())
return;
// get edges of the result

View File

@ -26,67 +26,57 @@
#include <TopoDS.hxx>
#include <stdio.h>
//=======================================================================
//function : prj
//purpose : Draw command for Conical and Cylindrical projection
//=======================================================================
static Standard_Integer prj(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
char newname[255];
if (n < 7) return 1;
TopoDS_Shape InpLine = DBRep::Get(a[2]);
TopoDS_Shape InpShape = DBRep::Get(a[3]);
Standard_Real DX=Draw::Atof(a[4]),DY=Draw::Atof(a[5]),DZ=Draw::Atof(a[6]);
gp_Dir TD(DX,DY,DZ);
BRepProj_Projection Prj(InpLine,InpShape,TD);
Standard_Integer i = 1;
char* temp = newname;
if (Prj.IsDone()) {
while (Prj.More()) {
Sprintf(newname,"%s_%d",a[1],i);
DBRep::Set(temp,Prj.Current());
//cout<<newname<<" ";
di<<newname<<" ";
i++;
Prj.Next();
}
{
if (n != 7)
{
di.PrintHelp(a[0]);
return 1;
}
//cout<<endl;
di<<"\n";
//
TopoDS_Shape anInputWire = DBRep::Get(a[2]);
TopoDS_Shape anInputShape = DBRep::Get(a[3]);
if (anInputWire.IsNull() || anInputShape.IsNull())
{
di << "Null input shapes\n";
return 1;
}
//
Standard_Real X = Draw::Atof(a[4]),
Y = Draw::Atof(a[5]),
Z = Draw::Atof(a[6]);
//
Standard_Boolean bCylProj = !strcmp(a[0], "prj");
//
BRepProj_Projection aPrj = bCylProj ?
BRepProj_Projection(anInputWire, anInputShape, gp_Dir(X, Y, Z)) :
BRepProj_Projection(anInputWire, anInputShape, gp_Pnt(X, Y, Z));
//
if (!aPrj.IsDone())
{
di << "Not done\n";
return 0;
}
//
for (Standard_Integer i = 1; aPrj.More(); aPrj.Next(), ++i)
{
char name[255];
Sprintf(name, "%s_%d", a[1], i);
DBRep::Set(name, aPrj.Current());
di << name << " ";
}
//
di << "\n";
return 0;
}
static Standard_Integer cprj(Draw_Interpretor& di, Standard_Integer n, const char** a)
{
char newname[255];
if (n < 7) return 1;
TopoDS_Shape InpLine = DBRep::Get(a[2]);
TopoDS_Shape InpShape = DBRep::Get(a[3]);
Standard_Real PX=Draw::Atof(a[4]),PY=Draw::Atof(a[5]),PZ=Draw::Atof(a[6]);
gp_Pnt P(PX,PY,PZ);
BRepProj_Projection Prj(InpLine,InpShape,P);
Standard_Integer i = 1;
char* temp = newname;
if (Prj.IsDone()) {
while (Prj.More()) {
Sprintf(newname,"%s_%d",a[1],i);
DBRep::Set(temp,Prj.Current());
//cout<<newname<<" ";
di<<newname<<" ";
i++;
Prj.Next();
}
}
//cout<<endl;
di<<"\n";
return 0;
}
/*********************************************************************************/
void BRepTest::ProjectionCommands(Draw_Interpretor& theCommands)
void BRepTest::ProjectionCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean loaded = Standard_False;
if (loaded) return;
@ -94,14 +84,11 @@ void BRepTest::ProjectionCommands(Draw_Interpretor& theCommands)
const char* g = "Projection of wire commands";
theCommands.Add("prj","prj result w s x y z: cylindrical projection of w (wire or edge) on s (faces) along direction",
__FILE__,
prj,g);
theCommands.Add("cprj","cprj result w s x y z: conical projection of w (wire or edge) on s (faces)",
__FILE__,
cprj,g);
theCommands.Add("prj","prj result w s x y z: "
"Cylindrical projection of w (wire or edge) on s (faces) along direction.\n",
__FILE__, prj, g);
//
theCommands.Add("cprj","cprj result w s x y z: "
"Conical projection of w (wire or edge) on s (faces).\n",
__FILE__, prj, g);
}

View File

@ -1308,14 +1308,24 @@ Standard_Real ElCLib::LineParameter (const gp_Ax1& L, const gp_Pnt& P)
//function : CircleParameter
//purpose :
//=======================================================================
Standard_Real ElCLib::CircleParameter (const gp_Ax2& Pos,
const gp_Pnt& P)
Standard_Real ElCLib::CircleParameter(const gp_Ax2& Pos,
const gp_Pnt& P)
{
gp_Vec aVec(Pos.Location(), P);
Standard_Real Teta = 0.0;
if (aVec.SquareMagnitude() > gp::Resolution())
Teta = (Pos.XDirection()).AngleWithRef(aVec, Pos.Direction());
if (aVec.SquareMagnitude() < gp::Resolution())
// coinciding points -> infinite number of parameters
return 0.0;
const gp_Dir& dir = Pos.Direction();
// Project vector on circle's plane
gp_XYZ aVProj = dir.XYZ().CrossCrossed(aVec.XYZ(), dir.XYZ());
if (aVProj.SquareModulus() < gp::Resolution())
return 0.0;
// Angle between X direction and projected vector
Standard_Real Teta = (Pos.XDirection()).AngleWithRef(aVProj, dir);
if (Teta < -1.e-16) Teta += PIPI;
else if (Teta < 0) Teta = 0;
return Teta;

View File

@ -113,6 +113,9 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
NbT = NbU = NbV = 10;
GeomAbs_CurveType myCtype = C.GetType();
myDone = Standard_False;
// Try analytic computation of extrema
Standard_Boolean isComputeAnalytic = Standard_True;
switch(myCtype) {
@ -233,6 +236,11 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
myExtElCS.Perform(C.Circle(), myS->Plane());
break;
}
else if (myStype == GeomAbs_Sphere)
{
myExtElCS.Perform(C.Circle(), myS->Sphere());
break;
}
}
Standard_FALLTHROUGH
case GeomAbs_Hyperbola:
@ -246,157 +254,225 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
Standard_FALLTHROUGH
default:
{
Extrema_GenExtCS Ext;
Ext.Initialize(*myS, NbU, NbV, mytolS);
if(myCtype == GeomAbs_Hyperbola) {
Standard_Real tmin = Max(-20., C.FirstParameter());
Standard_Real tmax = Min(20., C.LastParameter());
Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow
}
else {
if((myCtype == GeomAbs_Circle && NbT < 13) ||
(myCtype == GeomAbs_BSplineCurve && NbT < 13) )
{
NbT = 13;
}
Ext.Perform(C, NbT, mytolC);
}
isComputeAnalytic = Standard_False;
break;
}
}
myDone = Ext.IsDone();
if (myDone) {
Standard_Integer NbExt = Ext.NbExt();
Standard_Real T,U,V;
Extrema_POnCurv PC;
Extrema_POnSurf PS;
for (i = 1; i <= NbExt; i++) {
PC = Ext.PointOnCurve(i);
PS = Ext.PointOnSurface(i);
T = PC.Parameter();
if (isComputeAnalytic)
{
if (myExtElCS.IsDone())
{
myDone = Standard_True;
myIsPar = myExtElCS.IsParallel();
if (myIsPar)
{
mySqDist.Append(myExtElCS.SquareDistance(1));
}
else
{
Standard_Integer NbExt = myExtElCS.NbExt();
for (i = 1; i <= NbExt; i++)
{
Extrema_POnCurv PC;
Extrema_POnSurf PS;
myExtElCS.Points(i, PC, PS);
Standard_Real Ucurve = PC.Parameter();
Standard_Real U, V;
PS.Parameter(U, V);
AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i));
AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i));
}
//Add sharp points
Standard_Integer SolNumber = mySqDist.Length();
Standard_Address CopyC = (Standard_Address)&C;
Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)CopyC;
Standard_Integer NbIntervals = aC.NbIntervals(GeomAbs_C1);
TColStd_Array1OfReal SharpPoints(1, NbIntervals+1);
aC.Intervals(SharpPoints, GeomAbs_C1);
Extrema_ExtPS aProjPS;
aProjPS.Initialize (*myS,
myS->FirstUParameter(),
myS->LastUParameter(),
myS->FirstVParameter(),
myS->LastVParameter(),
mytolS,
mytolS);
for (i = 2; i < SharpPoints.Upper(); ++i)
if (mySqDist.Length() == 0 && NbExt > 0)
{
T = SharpPoints(i);
gp_Pnt aPnt = C.Value(T);
aProjPS.Perform (aPnt);
if (!aProjPS.IsDone())
continue;
Standard_Integer NbProj = aProjPS.NbExt(), jmin = 0;
Standard_Real MinSqDist = RealLast();
for (j = 1; j <= NbProj; j++)
// Analytical extrema seem to be out of curve/surface boundaries.
// Try extremity points of curve.
gp_Pnt aPOnC[2], aPOnS[2];
Standard_Real aT[2] = { myucinf, myucsup }, U[2], V[2];
Standard_Real aDist[2] = { -1, -1 };
for (i = 0; i < 2; ++i)
{
Standard_Real aSqDist = aProjPS.SquareDistance(j);
if (aSqDist < MinSqDist)
if (Precision::IsInfinite(aT[i]))
continue;
aPOnC[i] = C.Value(aT[i]);
switch (myStype)
{
MinSqDist = aSqDist;
jmin = j;
case GeomAbs_Plane:
{
ElSLib::Parameters(myS->Plane(), aPOnC[i], U[i], V[i]);
aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Plane());
break;
}
case GeomAbs_Sphere:
{
ElSLib::Parameters(myS->Sphere(), aPOnC[i], U[i], V[i]);
aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Sphere());
break;
}
case GeomAbs_Cylinder:
{
ElSLib::Parameters(myS->Cylinder(), aPOnC[i], U[i], V[i]);
aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Cylinder());
break;
}
case GeomAbs_Torus:
{
ElSLib::Parameters(myS->Torus(), aPOnC[i], U[i], V[i]);
aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Torus());
break;
}
case GeomAbs_Cone:
{
ElSLib::Parameters(myS->Cone(), aPOnC[i], U[i], V[i]);
aPOnS[i] = ElSLib::Value(U[i], V[i], myS->Cone());
break;
}
default:
continue;
}
aDist[i] = aPOnC[i].SquareDistance(aPOnS[i]);
}
if (jmin != 0)
Standard_Boolean bAdd[2] = {Standard_False, Standard_False};
// Choose solution to add
if (aDist[0] >= 0. && aDist[1] >= 0.)
{
aProjPS.Point(jmin).Parameter(U,V);
AddSolution(C, T, U, V,
aPnt, aProjPS.Point(jmin).Value(), MinSqDist);
Standard_Real aDiff = aDist[0] - aDist[1];
// Both computed -> take only minimal
if (Abs(aDiff) < Precision::Confusion())
// Add both
bAdd[0] = bAdd[1] = Standard_True;
else if (aDiff < 0)
// Add first
bAdd[0] = Standard_True;
else
// Add second
bAdd[1] = Standard_True;
}
}
//Cut sharp solutions to keep only minimum and maximum
Standard_Integer imin = SolNumber + 1, imax = mySqDist.Length();
for (i = SolNumber + 1; i <= mySqDist.Length(); i++)
{
if (mySqDist(i) < mySqDist(imin))
imin = i;
if (mySqDist(i) > mySqDist(imax))
imax = i;
}
if (mySqDist.Length() > SolNumber + 2)
{
Standard_Real MinSqDist = mySqDist(imin);
Standard_Real MaxSqDist = mySqDist(imax);
Extrema_POnCurv MinPC = myPOnC(imin);
Extrema_POnCurv MaxPC = myPOnC(imax);
Extrema_POnSurf MinPS = myPOnS(imin);
Extrema_POnSurf MaxPS = myPOnS(imax);
else if (aDist[0] >= 0.)
// Add first
bAdd[0] = Standard_True;
else if (aDist[1] >= 0.)
// Add second
bAdd[1] = Standard_True;
mySqDist.Remove(SolNumber + 1, mySqDist.Length());
myPOnC.Remove(SolNumber + 1, myPOnC.Length());
myPOnS.Remove(SolNumber + 1, myPOnS.Length());
mySqDist.Append(MinSqDist);
myPOnC.Append(MinPC);
myPOnS.Append(MinPS);
mySqDist.Append(MaxSqDist);
myPOnC.Append(MaxPC);
myPOnS.Append(MaxPS);
for (i = 0; i < 2; ++i)
{
if (bAdd[i])
AddSolution(C, aT[i], U[i], V[i], aPOnC[i], aPOnS[i], aDist[i]);
}
}
}
return;
}
break;
}
myDone = myExtElCS.IsDone();
if (myDone) {
myIsPar = myExtElCS.IsParallel();
if (myIsPar) {
mySqDist.Append(myExtElCS.SquareDistance(1));
// Elementary extrema is not done, try generic solution
Extrema_GenExtCS Ext;
Ext.Initialize(*myS, NbU, NbV, mytolS);
if (myCtype == GeomAbs_Hyperbola) {
Standard_Real tmin = Max(-20., C.FirstParameter());
Standard_Real tmax = Min(20., C.LastParameter());
Ext.Perform(C, NbT, tmin, tmax, mytolC); // to avoid overflow
}
else {
if ((myCtype == GeomAbs_Circle && NbT < 13) ||
(myCtype == GeomAbs_BSplineCurve && NbT < 13))
{
NbT = 13;
}
else {
Standard_Integer NbExt = myExtElCS.NbExt();
Standard_Real U, V;
for (i = 1; i <= NbExt; i++) {
Extrema_POnCurv PC;
Extrema_POnSurf PS;
myExtElCS.Points(i, PC, PS);
Standard_Real Ucurve = PC.Parameter();
PS.Parameter(U, V);
AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i));
}
if(mySqDist.Length() == 0 && NbExt > 0)
Ext.Perform(C, NbT, mytolC);
}
myDone = Ext.IsDone();
if (myDone) {
Standard_Integer NbExt = Ext.NbExt();
Standard_Real T, U, V;
Extrema_POnCurv PC;
Extrema_POnSurf PS;
for (i = 1; i <= NbExt; i++) {
PC = Ext.PointOnCurve(i);
PS = Ext.PointOnSurface(i);
T = PC.Parameter();
PS.Parameter(U, V);
AddSolution(C, T, U, V, PC.Value(), PS.Value(), Ext.SquareDistance(i));
}
//Add sharp points
Standard_Integer SolNumber = mySqDist.Length();
Standard_Address CopyC = (Standard_Address)&C;
Adaptor3d_Curve& aC = *(Adaptor3d_Curve*)CopyC;
Standard_Integer NbIntervals = aC.NbIntervals(GeomAbs_C1);
TColStd_Array1OfReal SharpPoints(1, NbIntervals + 1);
aC.Intervals(SharpPoints, GeomAbs_C1);
Extrema_ExtPS aProjPS;
aProjPS.Initialize(*myS,
myS->FirstUParameter(),
myS->LastUParameter(),
myS->FirstVParameter(),
myS->LastVParameter(),
mytolS,
mytolS);
for (i = 2; i < SharpPoints.Upper(); ++i)
{
T = SharpPoints(i);
gp_Pnt aPnt = C.Value(T);
aProjPS.Perform(aPnt);
if (!aProjPS.IsDone())
continue;
Standard_Integer NbProj = aProjPS.NbExt(), jmin = 0;
Standard_Real MinSqDist = RealLast();
for (j = 1; j <= NbProj; j++)
{
//Analytical extremas seem to be out of curve/surface boundaries.
//For plane it is possible to add extremity points of curve
if(myStype == GeomAbs_Plane)
Standard_Real aSqDist = aProjPS.SquareDistance(j);
if (aSqDist < MinSqDist)
{
gp_Pln aPln = myS->Plane();
gp_Pnt PC, PP;
if(!Precision::IsInfinite(myucinf))
{
PC = C.Value(myucinf);
ElSLib::PlaneParameters(aPln.Position(), PC, U, V);
PP = ElSLib::PlaneValue(U, V, aPln.Position());
AddSolution(C, myucinf, U, V, PC, PP, PC.SquareDistance(PP));
}
if(!Precision::IsInfinite(myucsup))
{
PC = C.Value(myucsup);
ElSLib::PlaneParameters(aPln.Position(), PC, U, V);
PP = ElSLib::PlaneValue(U, V, aPln.Position());
AddSolution(C, myucsup, U, V, PC, PP, PC.SquareDistance(PP));
}
MinSqDist = aSqDist;
jmin = j;
}
}
if (jmin != 0)
{
aProjPS.Point(jmin).Parameter(U, V);
AddSolution(C, T, U, V,
aPnt, aProjPS.Point(jmin).Value(), MinSqDist);
}
}
//Cut sharp solutions to keep only minimum and maximum
Standard_Integer imin = SolNumber + 1, imax = mySqDist.Length();
for (i = SolNumber + 1; i <= mySqDist.Length(); i++)
{
if (mySqDist(i) < mySqDist(imin))
imin = i;
if (mySqDist(i) > mySqDist(imax))
imax = i;
}
if (mySqDist.Length() > SolNumber + 2)
{
Standard_Real MinSqDist = mySqDist(imin);
Standard_Real MaxSqDist = mySqDist(imax);
Extrema_POnCurv MinPC = myPOnC(imin);
Extrema_POnCurv MaxPC = myPOnC(imax);
Extrema_POnSurf MinPS = myPOnS(imin);
Extrema_POnSurf MaxPS = myPOnS(imax);
mySqDist.Remove(SolNumber + 1, mySqDist.Length());
myPOnC.Remove(SolNumber + 1, myPOnC.Length());
myPOnS.Remove(SolNumber + 1, myPOnS.Length());
mySqDist.Append(MinSqDist);
myPOnC.Append(MinPC);
myPOnS.Append(MinPS);
mySqDist.Append(MaxSqDist);
myPOnC.Append(MaxPC);
myPOnS.Append(MaxPS);
}
}
}

View File

@ -33,11 +33,13 @@
#include <gp_Vec.hxx>
#include <IntAna_IntConicQuad.hxx>
#include <IntAna_Quadric.hxx>
#include <IntAna_QuadQuadGeo.hxx>
#include <Precision.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_InfiniteSolutions.hxx>
#include <StdFail_NotDone.hxx>
#include <TColStd_ListOfInteger.hxx>
Extrema_ExtElCS::Extrema_ExtElCS()
{
@ -534,19 +536,137 @@ void Extrema_ExtElCS::Perform(const gp_Circ& ,
//=======================================================================
//function : Extrema_ExtElCS
//purpose : Circle/Sphere
//=======================================================================
Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
const gp_Sphere& S)
{ Perform(C, S);}
//void Extrema_ExtElCS::Perform(const gp_Circ& C,
// const gp_Sphere& S)
void Extrema_ExtElCS::Perform(const gp_Circ& ,
const gp_Sphere& )
const gp_Sphere& S)
{
throw Standard_NotImplemented();
Perform(C, S);
}
//=======================================================================
//function : Perform
//purpose : Circle/Sphere
//=======================================================================
void Extrema_ExtElCS::Perform(const gp_Circ& C,
const gp_Sphere& S)
{
myDone = Standard_False;
if (gp_Lin(C.Axis()).SquareDistance(S.Location()) < Precision::SquareConfusion())
{
// Circle and sphere are parallel
myIsPar = Standard_True;
myDone = Standard_True;
// Compute distance from circle to the sphere
Standard_Real aSqDistLoc = C.Location().SquareDistance(S.Location());
Standard_Real aSqDist = aSqDistLoc + C.Radius() * C.Radius();
Standard_Real aDist = sqrt(aSqDist) - S.Radius();
mySqDist = new TColStd_HArray1OfReal(1, 1);
mySqDist->SetValue(1, aDist * aDist);
return;
}
// Intersect sphere with circle's plane
gp_Pln CPln(C.Location(), C.Axis().Direction());
IntAna_QuadQuadGeo anInter(CPln, S);
if (!anInter.IsDone())
// not done
return;
if (anInter.TypeInter() != IntAna_Circle)
{
// Intersection is empty or just a point.
// The parallel case has already been considered,
// thus, here we have to find only one minimal solution
myNbExt = 1;
myDone = Standard_True;
mySqDist = new TColStd_HArray1OfReal(1, 1);
myPoint1 = new Extrema_HArray1OfPOnCurv(1, 1);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, 1);
// Compute parameter on circle
const Standard_Real aT = ElCLib::Parameter(C, S.Location());
// Compute point on circle
gp_Pnt aPOnC = ElCLib::Value(aT, C);
// Compute parameters on sphere
Standard_Real aU, aV;
ElSLib::Parameters(S, aPOnC, aU, aV);
// Compute point on sphere
gp_Pnt aPOnS = ElSLib::Value(aU, aV, S);
// Save solution
myPoint1->SetValue(1, Extrema_POnCurv(aT, aPOnC));
myPoint2->SetValue(1, Extrema_POnSurf(aU, aV, aPOnS));
mySqDist->SetValue(1, aPOnC.SquareDistance(aPOnS));
return;
}
// Here, the intersection is a circle
// Intersection circle
gp_Circ aCInt = anInter.Circle(1);
// Perform intersection of the input circle with the intersection circle
Extrema_ExtElC anExtC(C, aCInt);
Standard_Boolean isExtremaCircCircValid = anExtC.IsDone() // Check if intersection is done
&& !anExtC.IsParallel() // Parallel case has already been considered
&& anExtC.NbExt() > 0; // Check that some solutions have been found
if (!isExtremaCircCircValid)
// not done
return;
myDone = Standard_True;
// Few solutions
Standard_Real aNbExt = anExtC.NbExt();
// Find the minimal distance
Standard_Real aMinSqDist = ::RealLast();
for (Standard_Integer i = 1; i <= aNbExt; ++i)
{
Standard_Real aSqDist = anExtC.SquareDistance(i);
if (aSqDist < aMinSqDist)
aMinSqDist = aSqDist;
}
// Collect all solutions close to the minimal one
TColStd_ListOfInteger aSols;
for (Standard_Integer i = 1; i <= aNbExt; ++i)
{
Standard_Real aDiff = anExtC.SquareDistance(i) - aMinSqDist;
if (aDiff < Precision::SquareConfusion())
aSols.Append(i);
}
// Save all minimal solutions
myNbExt = aSols.Extent();
mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
TColStd_ListIteratorOfListOfInteger it(aSols);
for (Standard_Integer iSol = 1; it.More(); it.Next(), ++iSol)
{
Extrema_POnCurv P1, P2;
anExtC.Points(it.Value(), P1, P2);
// Compute parameters on sphere
Standard_Real aU, aV;
ElSLib::Parameters(S, P1.Value(), aU, aV);
// Compute point on sphere
gp_Pnt aPOnS = ElSLib::Value(aU, aV, S);
// Save solution
myPoint1->SetValue(iSol, P1);
myPoint2->SetValue(iSol, Extrema_POnSurf(aU, aV, aPOnS));
mySqDist->SetValue(iSol, P1.Value().SquareDistance(aPOnS));
}
}
Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,

View File

@ -86,7 +86,7 @@ void GeomAPI_ExtremaCurveSurface::Init
Extrema_ExtCS theExtCS(TheCurve,TheSurface,Tol,Tol);
myExtCS = theExtCS;
myIsDone = myExtCS.IsDone() && ( myExtCS.NbExt() > 0);
myIsDone = myExtCS.IsDone() && (myExtCS.IsParallel() || myExtCS.NbExt() > 0);
if ( myIsDone) {
@ -129,7 +129,7 @@ void GeomAPI_ExtremaCurveSurface::Init
Wmin,Wmax,Umin,Umax,Vmin,Vmax,Tol,Tol);
myExtCS = theExtCS;
myIsDone = myExtCS.IsDone() && ( myExtCS.NbExt() > 0);
myIsDone = myExtCS.IsDone() && (myExtCS.IsParallel() || myExtCS.NbExt() > 0);
if ( myIsDone) {

View File

@ -407,7 +407,8 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
}
// Since GeomAPI cannot provide access to flag directly.
isInfinitySolutions = Ex.Extrema().IsParallel();
aMinDist = Ex.LowerDistance();
if (isInfinitySolutions)
aMinDist = Ex.LowerDistance();
}
else if (C1 && S2)
{
@ -425,6 +426,9 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
aPrms[2].Append(aU2);
aPrms[3].Append(aV2);
}
isInfinitySolutions = Ex.Extrema().IsParallel();
if (isInfinitySolutions)
aMinDist = Ex.LowerDistance();
}
else if (S1 && C2)
{
@ -442,6 +446,9 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const
aPrms[1].Append(aV1);
aPrms[2].Append(aU2);
}
isInfinitySolutions = Ex.Extrema().IsParallel();
if (isInfinitySolutions)
aMinDist = Ex.LowerDistance();
}
else if (S1 && S2)
{

View File

@ -1,6 +1,7 @@
IntPolyh_Array.hxx
IntPolyh_ArrayOfEdges.hxx
IntPolyh_ArrayOfPoints.hxx
IntPolyh_ArrayOfPointNormal.hxx
IntPolyh_ArrayOfSectionLines.hxx
IntPolyh_ArrayOfTangentZones.hxx
IntPolyh_ArrayOfTriangles.hxx
@ -11,7 +12,6 @@ IntPolyh_Edge.cxx
IntPolyh_Edge.hxx
IntPolyh_Intersection.cxx
IntPolyh_Intersection.hxx
IntPolyh_Intersection_1.cxx
IntPolyh_ListOfCouples.hxx
IntPolyh_MaillageAffinage.cxx
IntPolyh_MaillageAffinage.hxx
@ -23,5 +23,7 @@ IntPolyh_SectionLine.hxx
IntPolyh_SeqOfStartPoints.hxx
IntPolyh_StartPoint.cxx
IntPolyh_StartPoint.hxx
IntPolyh_Tools.cxx
IntPolyh_Tools.hxx
IntPolyh_Triangle.cxx
IntPolyh_Triangle.hxx

View File

@ -1,4 +1,5 @@
// Copyright (c) 1999-2014 OPEN CASCADE SAS
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2017 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
@ -11,9 +12,21 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
inline Standard_Boolean IntTools_BeanFaceIntersector::IsDone() const
{
return myIsDone;
}
#ifndef IntPolyh_ArrayOfPointNormal_HeaderFile
#define IntPolyh_ArrayOfPointNormal_HeaderFile
#include <IntPolyh_Array.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
//! Auxiliary structure to represent pair of point and
//! normal vector in this point on the surface.
struct IntPolyh_PointNormal
{
gp_Pnt Point;
gp_Vec Normal;
};
typedef IntPolyh_Array <IntPolyh_PointNormal> IntPolyh_ArrayOfPointNormal;
#endif

View File

@ -14,292 +14,398 @@
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// modified by Edward AGAPOV (eap) Tue Jan 22 12:29:55 2002 (occ53)
// Modified by skv - Thu Sep 25 18:24:29 2003 OCC567
#include <IntPolyh_Intersection.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <IntPolyh_Couple.hxx>
#include <IntPolyh_Intersection.hxx>
#include <IntPolyh_CoupleMapHasher.hxx>
#include <IntPolyh_MaillageAffinage.hxx>
#include <IntPolyh_SectionLine.hxx>
#include <IntPolyh_StartPoint.hxx>
#include <IntPolyh_Tools.hxx>
#include <IntPolyh_Triangle.hxx>
#include <NCollection_Map.hxx>
#include <IntPolyh_CoupleMapHasher.hxx>
Standard_Integer MYDISPLAY = 0;
Standard_Integer MYPRINT = 0;
static Standard_Boolean IsAdvRequired(IntPolyh_PMaillageAffinage& theMaillage);
IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
const Handle(Adaptor3d_HSurface)& S2)
static Standard_Integer ComputeIntersection(IntPolyh_PMaillageAffinage& theMaillage);
static Standard_Boolean AnalyzeIntersection(IntPolyh_PMaillageAffinage& theMaillage);
//=======================================================================
//function : IntPolyh_Intersection
//purpose :
//=======================================================================
IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2)
{
myNbSU1 = -1;
myNbSV1 = -1;
myNbSU2 = -1;
myNbSV2 = -1;
mySurf1 = S1;
mySurf2 = S2;
done = Standard_False;
TSectionLines.Init(1000);
TTangentZones.Init(10000);
mySurf1 = theS1;
mySurf2 = theS2;
myNbSU1 = 10;
myNbSV1 = 10;
myNbSU2 = 10;
myNbSV2 = 10;
myIsDone = Standard_False;
mySectionLines.Init(1000);
myTangentZones.Init(10000);
Perform();
}
IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
const Standard_Integer NbSU1,
const Standard_Integer NbSV1,
const Handle(Adaptor3d_HSurface)& S2,
const Standard_Integer NbSU2,
const Standard_Integer NbSV2)
//=======================================================================
//function : IntPolyh_Intersection
//purpose :
//=======================================================================
IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& theS1,
const Standard_Integer theNbSU1,
const Standard_Integer theNbSV1,
const Handle(Adaptor3d_HSurface)& theS2,
const Standard_Integer theNbSU2,
const Standard_Integer theNbSV2)
{
myNbSU1 = NbSU1;
myNbSV1 = NbSV1;
myNbSU2 = NbSU2;
myNbSV2 = NbSV2;
mySurf1 = S1;
mySurf2 = S2;
done = Standard_False;
TSectionLines.Init(1000);
TTangentZones.Init(10000);
mySurf1 = theS1;
mySurf2 = theS2;
myNbSU1 = theNbSU1;
myNbSV1 = theNbSV1;
myNbSU2 = theNbSU2;
myNbSV2 = theNbSV2;
myIsDone = Standard_False;
mySectionLines.Init(1000);
myTangentZones.Init(10000);
Perform();
}
void IntPolyh_Intersection::Perform() {
//=======================================================================
//function : IntPolyh_Intersection
//purpose :
//=======================================================================
IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& theS1,
const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const Handle(Adaptor3d_HSurface)& theS2,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2)
{
mySurf1 = theS1;
mySurf2 = theS2;
myNbSU1 = theUPars1.Length();
myNbSV1 = theVPars1.Length();
myNbSU2 = theUPars2.Length();
myNbSV2 = theVPars2.Length();
myIsDone = Standard_False;
mySectionLines.Init(1000);
myTangentZones.Init(10000);
Perform(theUPars1, theVPars1, theUPars2, theVPars2);
}
done = Standard_True;
//=======================================================================
//function : GetLinePoint
//purpose :
//=======================================================================
void IntPolyh_Intersection::GetLinePoint(const Standard_Integer Indexl,
const Standard_Integer Indexp,
Standard_Real &x,
Standard_Real &y,
Standard_Real &z,
Standard_Real &u1,
Standard_Real &v1,
Standard_Real &u2,
Standard_Real &v2,
Standard_Real &incidence) const
{
const IntPolyh_SectionLine &msl = mySectionLines[Indexl - 1];
const IntPolyh_StartPoint &sp = msl[Indexp - 1];
x = sp.X();
y = sp.Y();
z = sp.Z();
u1 = sp.U1();
v1 = sp.V1();
u2 = sp.U2();
v2 = sp.V2();
incidence = sp.GetAngle();
}
Standard_Boolean isStdDone = Standard_False;
Standard_Boolean isAdvDone = Standard_False;
Standard_Integer nbCouplesStd = 0;
Standard_Integer nbCouplesAdv = 0;
IntPolyh_PMaillageAffinage aPMaillageStd = 0;
IntPolyh_PMaillageAffinage aPMaillageFF = 0;
IntPolyh_PMaillageAffinage aPMaillageFR = 0;
IntPolyh_PMaillageAffinage aPMaillageRF = 0;
IntPolyh_PMaillageAffinage aPMaillageRR = 0;
//=======================================================================
//function : GetTangentZonePoint
//purpose :
//=======================================================================
void IntPolyh_Intersection::GetTangentZonePoint(const Standard_Integer Indexz,
const Standard_Integer /*Indexp*/,
Standard_Real &x,
Standard_Real &y,
Standard_Real &z,
Standard_Real &u1,
Standard_Real &v1,
Standard_Real &u2,
Standard_Real &v2) const
{
const IntPolyh_StartPoint &sp = myTangentZones[Indexz - 1];
x = sp.X();
y = sp.Y();
z = sp.Z();
u1 = sp.U1();
v1 = sp.V1();
u2 = sp.U2();
v2 = sp.V2();
}
isStdDone = PerformStd(aPMaillageStd,nbCouplesStd);
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void IntPolyh_Intersection::Perform()
{
// Prepare the sampling of the surfaces - UV parameters of the triangulation nodes
TColStd_Array1OfReal UPars1, VPars1, UPars2, VPars2;
IntPolyh_Tools::MakeSampling(mySurf1, myNbSU1, myNbSV1, Standard_False, UPars1, VPars1);
IntPolyh_Tools::MakeSampling(mySurf2, myNbSU2, myNbSV2, Standard_False, UPars2, VPars2);
// default interference done well, use it
if(isStdDone && nbCouplesStd > 10) {
aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
// Perform intersection
Perform(UPars1, VPars1, UPars2, VPars2);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void IntPolyh_Intersection::Perform(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2)
{
myIsDone = Standard_True;
// Compute the deflection of the given sampling if it is not set
Standard_Real aDeflTol1 = IntPolyh_Tools::ComputeDeflection(mySurf1, theUPars1, theVPars1);
Standard_Real aDeflTol2 = IntPolyh_Tools::ComputeDeflection(mySurf2, theUPars2, theVPars2);
// Perform standard intersection
IntPolyh_PMaillageAffinage pMaillageStd = 0;
Standard_Integer nbCouplesStd = 0;
Standard_Boolean isStdDone = PerformStd(theUPars1, theVPars1,
theUPars2, theVPars2,
aDeflTol1, aDeflTol2,
pMaillageStd, nbCouplesStd);
if (!isStdDone)
{
// Intersection not done
myIsDone = Standard_False;
if (pMaillageStd) delete pMaillageStd;
return;
}
// default interference done, but too few interferences foud;
// use advanced interference
else if(isStdDone && nbCouplesStd <= 10) {
isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
// advanced interference found
if(isAdvDone && nbCouplesAdv > 0) {
aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
if (!IsAdvRequired(pMaillageStd))
{
// Default interference done well, use it
pMaillageStd->StartPointsChain(mySectionLines, myTangentZones);
}
else
{
// Default intersection is done, but too few interferences found.
// Perform advanced intersection - perform intersection four times with different shifts.
IntPolyh_PMaillageAffinage pMaillageFF = 0;
IntPolyh_PMaillageAffinage pMaillageFR = 0;
IntPolyh_PMaillageAffinage pMaillageRF = 0;
IntPolyh_PMaillageAffinage pMaillageRR = 0;
Standard_Integer nbCouplesAdv = 0;
Standard_Boolean isAdvDone = PerformAdv(theUPars1, theVPars1,
theUPars2, theVPars2,
aDeflTol1, aDeflTol2,
pMaillageFF,
pMaillageFR,
pMaillageRF,
pMaillageRR,
nbCouplesAdv);
if (isAdvDone && nbCouplesAdv > 0)
{
// Advanced interference found
pMaillageFF->StartPointsChain(mySectionLines, myTangentZones);
pMaillageFR->StartPointsChain(mySectionLines, myTangentZones);
pMaillageRF->StartPointsChain(mySectionLines, myTangentZones);
pMaillageRR->StartPointsChain(mySectionLines, myTangentZones);
}
else {
// use result of default
if(nbCouplesStd > 0)
aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
else
{
// Advanced intersection not done or no intersection is found -> use standard intersection
if (nbCouplesStd > 0)
pMaillageStd->StartPointsChain(mySectionLines, myTangentZones);
}
}
// default interference faild, use advanced
else {
// isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
// if(isAdvDone && nbCouplesAdv > 0) {cout << "4adv done, nbc: " << nbCouplesAdv << endl;
// aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
// aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
// aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
// aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
// }
// Clean up
if (pMaillageFF) delete pMaillageFF;
if (pMaillageFR) delete pMaillageFR;
if (pMaillageRF) delete pMaillageRF;
if (pMaillageRR) delete pMaillageRR;
}
// accept result
nbsectionlines = TSectionLines.NbItems();
nbtangentzones = TTangentZones.NbItems();
// clean up
if(aPMaillageStd) delete aPMaillageStd;
if(aPMaillageFF) delete aPMaillageFF;
if(aPMaillageFR) delete aPMaillageFR;
if(aPMaillageRF) delete aPMaillageRF;
if(aPMaillageRR) delete aPMaillageRR;
// verify
if(!isStdDone && !isAdvDone)
done = Standard_False;
if (pMaillageStd) delete pMaillageStd;
}
Standard_Boolean IntPolyh_Intersection::IsDone() const {
return(done);
}
Standard_Integer IntPolyh_Intersection::NbSectionLines() const {
return(nbsectionlines);
}
Standard_Integer IntPolyh_Intersection::NbPointsInLine(const Standard_Integer IndexLine) const {
return(TSectionLines[IndexLine-1].NbStartPoints());
}
Standard_Integer IntPolyh_Intersection::NbPointsInTangentZone(const Standard_Integer) const {
//-- IndexLine--; (pas implemente) Attention : Tableaux de 0 a n-1
// eap
// return(TTangentZones.NbTangentZones());
return 1;
}
Standard_Integer IntPolyh_Intersection::NbTangentZones() const {
return(nbtangentzones);
}
void IntPolyh_Intersection::GetLinePoint(const Standard_Integer Indexl,
const Standard_Integer Indexp,
Standard_Real &x,
Standard_Real &y,
Standard_Real &z,
Standard_Real &u1,
Standard_Real &v1,
Standard_Real &u2,
Standard_Real &v2,
Standard_Real &incidence) const {
const IntPolyh_SectionLine &msl=TSectionLines[Indexl-1];
const IntPolyh_StartPoint &sp=msl[Indexp-1];
x=sp.X();
y=sp.Y();
z=sp.Z();
u1=sp.U1();
v1=sp.V1();
u2=sp.U2();
v2=sp.V2();
incidence=sp.GetAngle();
}
void IntPolyh_Intersection::GetTangentZonePoint(const Standard_Integer Indexz,
const Standard_Integer /*Indexp*/,
Standard_Real &x,
Standard_Real &y,
Standard_Real &z,
Standard_Real &u1,
Standard_Real &v1,
Standard_Real &u2,
Standard_Real &v2) const {
//-- Indexz--; tableaux C
// eap
//const IntPolyh_StartPoint &sp=TTangentZones[Indexp-1];
const IntPolyh_StartPoint &sp=TTangentZones[Indexz-1];
x=sp.X();
y=sp.Y();
z=sp.Z();
u1=sp.U1();
v1=sp.V1();
u2=sp.U2();
v2=sp.V2();
}
// Modified by skv - Thu Sep 25 18:07:41 2003 OCC567 Begin
//=======================================================================
//function : PerformMaillage
//purpose : Computes MaillageAffinage
//function : PerformStd
//purpose :
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformMaillage
(const Standard_Boolean isFirstFwd,
const Standard_Boolean isSecondFwd,
IntPolyh_PMaillageAffinage &theMaillageS)
Standard_Boolean IntPolyh_Intersection::PerformStd(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
IntPolyh_PMaillageAffinage& theMaillageS,
Standard_Integer& theNbCouples)
{
if (myNbSU1 == -1)
theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, mySurf2, MYPRINT);
else
theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, myNbSU1, myNbSV1,
mySurf2, myNbSU2, myNbSV2,
MYPRINT);
Standard_Boolean isDone = PerformMaillage(theUPars1, theVPars1,
theUPars2, theVPars2,
theDeflTol1, theDeflTol2,
theMaillageS);
theNbCouples = (isDone) ? (theMaillageS->GetCouples().Extent()) : 0;
return isDone;
}
theMaillageS->FillArrayOfPnt(1, isFirstFwd);
theMaillageS->FillArrayOfPnt(2, isSecondFwd);
Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
xx0, yy0, zz0, xx1, yy1, zz1);
theMaillageS->FillArrayOfTriangles(1);
theMaillageS->FillArrayOfTriangles(2);
theMaillageS->FillArrayOfEdges(1);
theMaillageS->FillArrayOfEdges(2);
//=======================================================================
//function : PerformAdv
//purpose :
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformAdv(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
IntPolyh_PMaillageAffinage& theMaillageFF,
IntPolyh_PMaillageAffinage& theMaillageFR,
IntPolyh_PMaillageAffinage& theMaillageRF,
IntPolyh_PMaillageAffinage& theMaillageRR,
Standard_Integer& theNbCouples)
{
// Compute the points on the surface and normal directions in these points
IntPolyh_ArrayOfPointNormal aPoints1, aPoints2;
IntPolyh_Tools::FillArrayOfPointNormal(mySurf1, theUPars1, theVPars1, aPoints1);
IntPolyh_Tools::FillArrayOfPointNormal(mySurf2, theUPars2, theVPars2, aPoints2);
theMaillageS->TrianglesDeflectionsRefinementBSB();
// Perform intersection with the different shifts of the triangles
Standard_Boolean isDone =
PerformMaillage(theUPars1, theVPars1, theUPars2, theVPars2, // sampling
theDeflTol1, theDeflTol2, // deflection tolerance
aPoints1, aPoints2, // points and normals
Standard_True , Standard_False, // shift
theMaillageFR)
&&
PerformMaillage(theUPars1, theVPars1, theUPars2, theVPars2, // sampling
theDeflTol1, theDeflTol2, // deflection tolerance
aPoints1, aPoints2, // points and normals
Standard_False, Standard_True, // shift
theMaillageRF)
&&
PerformMaillage(theUPars1, theVPars1, theUPars2, theVPars2, // sampling
theDeflTol1, theDeflTol2, // deflection tolerance
aPoints1, aPoints2, // points and normals
Standard_True, Standard_True, // shift
theMaillageFF)
&&
PerformMaillage(theUPars1, theVPars1, theUPars2, theVPars2, // sampling
theDeflTol1, theDeflTol2, // deflection tolerance
aPoints1, aPoints2, // points and normals
Standard_False, Standard_False, // shift
theMaillageRR);
Standard_Integer FinTTC = theMaillageS->TriangleCompare();
if (isDone)
{
theNbCouples = theMaillageFF->GetCouples().Extent() +
theMaillageFR->GetCouples().Extent() +
theMaillageRF->GetCouples().Extent() +
theMaillageRR->GetCouples().Extent();
// if too many intersections, consider surfaces parallel (eap)
if(FinTTC > 200 &&
(FinTTC >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
FinTTC >= theMaillageS->GetArrayOfTriangles(2).NbItems()) ) {
return Standard_False;
// Merge couples
if(theNbCouples > 0)
MergeCouples(theMaillageFF->GetCouples(),
theMaillageFR->GetCouples(),
theMaillageRF->GetCouples(),
theMaillageRR->GetCouples());
}
return Standard_True;
return isDone;
}
//=======================================================================
//function : PerformMaillage
//purpose : Computes standard MaillageAffinage (without shift)
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformMaillage(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
IntPolyh_PMaillageAffinage& theMaillage)
{
theMaillage =
new IntPolyh_MaillageAffinage(mySurf1, theUPars1.Length(), theVPars1.Length(),
mySurf2, theUPars2.Length(), theVPars2.Length(),
0);
theMaillage->FillArrayOfPnt(1, theUPars1, theVPars1, &theDeflTol1);
theMaillage->FillArrayOfPnt(2, theUPars2, theVPars2, &theDeflTol2);
Standard_Integer FinTTC = ComputeIntersection(theMaillage);
// If no intersecting triangles are found, try enlarged surfaces
if (FinTTC == 0)
{
// Check if enlarge for the surfaces is possible
Standard_Boolean isEnlargeU1, isEnlargeV1, isEnlargeU2, isEnlargeV2;
IntPolyh_Tools::IsEnlargePossible(mySurf1, isEnlargeU1, isEnlargeV1);
IntPolyh_Tools::IsEnlargePossible(mySurf2, isEnlargeU2, isEnlargeV2);
if (isEnlargeU1 || isEnlargeV1 || isEnlargeU2 || isEnlargeV2)
{
theMaillage->SetEnlargeZone(Standard_True);
// Make new points on the enlarged surface
theMaillage->FillArrayOfPnt(1);
theMaillage->FillArrayOfPnt(2);
// Compute intersection
ComputeIntersection(theMaillage);
theMaillage->SetEnlargeZone(Standard_False);
}
}
// if too many intersections, consider surfaces parallel
return AnalyzeIntersection(theMaillage);
}
//=======================================================================
//function : PerformMaillage
//purpose : Computes MaillageAffinage
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformMaillage(IntPolyh_PMaillageAffinage &theMaillageS)
Standard_Boolean IntPolyh_Intersection::PerformMaillage(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
const IntPolyh_ArrayOfPointNormal& thePoints1,
const IntPolyh_ArrayOfPointNormal& thePoints2,
const Standard_Boolean theIsFirstFwd,
const Standard_Boolean theIsSecondFwd,
IntPolyh_PMaillageAffinage& theMaillage)
{
if (myNbSU1 == -1)
theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, mySurf2, MYPRINT);
else
theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, myNbSU1, myNbSV1,
mySurf2, myNbSU2, myNbSV2,
MYPRINT);
theMaillage =
new IntPolyh_MaillageAffinage(mySurf1, theUPars1.Length(), theVPars1.Length(),
mySurf2, theUPars2.Length(), theVPars2.Length(),
0);
theMaillageS->FillArrayOfPnt(1);
theMaillageS->FillArrayOfPnt(2);
Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
xx0, yy0, zz0, xx1, yy1, zz1);
theMaillageS->FillArrayOfTriangles(1);
theMaillageS->FillArrayOfTriangles(2);
theMaillageS->FillArrayOfEdges(1);
theMaillageS->FillArrayOfEdges(2);
theMaillage->FillArrayOfPnt(1, theIsFirstFwd , thePoints1, theUPars1, theVPars1, theDeflTol1);
theMaillage->FillArrayOfPnt(2, theIsSecondFwd, thePoints2, theUPars2, theVPars2, theDeflTol2);
theMaillageS->TrianglesDeflectionsRefinementBSB();
ComputeIntersection(theMaillage);
Standard_Integer FinTTC = theMaillageS->TriangleCompare();
if( FinTTC == 0 ) {
Standard_Boolean myZone = Standard_True;
theMaillageS->SetEnlargeZone( myZone );
theMaillageS->FillArrayOfPnt(1);
theMaillageS->FillArrayOfPnt(2);
theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
xx0, yy0, zz0, xx1, yy1, zz1);
theMaillageS->FillArrayOfTriangles(1);
theMaillageS->FillArrayOfTriangles(2);
theMaillageS->FillArrayOfEdges(1);
theMaillageS->FillArrayOfEdges(2);
theMaillageS->TrianglesDeflectionsRefinementBSB();
FinTTC = theMaillageS->TriangleCompare();
myZone = Standard_False;
theMaillageS->SetEnlargeZone( myZone );
}
return Standard_True;
return AnalyzeIntersection(theMaillage);
}
//=======================================================================
@ -308,7 +414,6 @@ Standard_Boolean IntPolyh_Intersection::PerformMaillage(IntPolyh_PMaillageAffina
// If some are detected it leaves the couple in only one list
// deleting from others.
//=======================================================================
void IntPolyh_Intersection::MergeCouples(IntPolyh_ListOfCouples &anArrayFF,
IntPolyh_ListOfCouples &anArrayFR,
IntPolyh_ListOfCouples &anArrayRF,
@ -331,45 +436,100 @@ void IntPolyh_Intersection::MergeCouples(IntPolyh_ListOfCouples &anArrayFF,
}
//=======================================================================
//function : PerformStd
//purpose :
//function : IsAdvRequired
//purpose : Analyzes the standard intersection on the angles between triangles.
// If the angle between some of the interfering triangles is
// too small (less than 5 deg), the advanced intersection is required.
// Otherwise, the standard intersection is considered satisfactory.
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformStd(IntPolyh_PMaillageAffinage& MaillageS,
Standard_Integer& NbCouples)
Standard_Boolean IsAdvRequired(IntPolyh_PMaillageAffinage& theMaillage)
{
Standard_Boolean isdone = PerformMaillage(MaillageS);
NbCouples = (isdone) ? (MaillageS->GetCouples().Extent()) : 0;
return isdone;
}
if (!theMaillage)
return Standard_True;
//=======================================================================
//function : PerformAdv
//purpose :
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformAdv(IntPolyh_PMaillageAffinage& MaillageFF,
IntPolyh_PMaillageAffinage& MaillageFR,
IntPolyh_PMaillageAffinage& MaillageRF,
IntPolyh_PMaillageAffinage& MaillageRR,
Standard_Integer& NbCouples)
{
Standard_Boolean isdone = Standard_True;
NbCouples = 0;
// Interfering triangles
IntPolyh_ListOfCouples& Couples = theMaillage->GetCouples();
// Number of interfering pairs
Standard_Integer aNbCouples = Couples.Extent();
// Flag to define whether advanced intersection is required or not
Standard_Boolean isAdvReq = (aNbCouples == 0);
if (isAdvReq)
// No interfering triangles are found -> perform advanced intersection
return isAdvReq;
if(!PerformMaillage(Standard_True,Standard_False,MaillageFR) ||
!PerformMaillage(Standard_False,Standard_True,MaillageRF) ||
!PerformMaillage(Standard_True,Standard_True,MaillageFF) ||
!PerformMaillage(Standard_False,Standard_False,MaillageRR) )
isdone = Standard_False;
if (aNbCouples > 10)
// Enough interfering triangles are found -> no need to perform advanced intersection
return isAdvReq;
if(isdone) {
NbCouples = MaillageFF->GetCouples().Extent() +
MaillageFR->GetCouples().Extent() +
MaillageRF->GetCouples().Extent() +
MaillageRR->GetCouples().Extent();
if(NbCouples > 0)
MergeCouples(MaillageFF->GetCouples(),MaillageFR->GetCouples(),
MaillageRF->GetCouples(),MaillageRR->GetCouples());
const Standard_Real anEps = .996; //~ cos of 5 deg
IntPolyh_ListIteratorOfListOfCouples aIt(Couples);
for(; aIt.More(); aIt.Next())
{
if (Abs(aIt.Value().Angle()) > anEps)
{
// The angle between interfering triangles is small -> perform advanced
// intersection to make intersection more precise
isAdvReq = Standard_True;
break;
}
}
return isdone;
return isAdvReq;
}
//=======================================================================
//function : ComputeIntersection
//purpose : Computes the intersection of the triangles
//=======================================================================
Standard_Integer ComputeIntersection(IntPolyh_PMaillageAffinage& theMaillage)
{
if (!theMaillage)
return 0;
// Compute common box and mark the points inside that box
theMaillage->CommonBox();
// Make triangles
theMaillage->FillArrayOfTriangles(1);
theMaillage->FillArrayOfTriangles(2);
// Make edges
theMaillage->FillArrayOfEdges(1);
theMaillage->FillArrayOfEdges(2);
// Deflection refinement
theMaillage->TrianglesDeflectionsRefinementBSB();
return theMaillage->TriangleCompare();
}
//=======================================================================
//function : AnalyzeIntersection
//purpose : Analyzes the intersection on the number of interfering triangles
//=======================================================================
Standard_Boolean AnalyzeIntersection(IntPolyh_PMaillageAffinage& theMaillage)
{
if (!theMaillage)
return Standard_False;
IntPolyh_ListOfCouples& Couples = theMaillage->GetCouples();
Standard_Integer FinTTC = Couples.Extent();
if(FinTTC > 200)
{
const Standard_Real eps = .996; //~ cos of 5deg.
Standard_Integer npara = 0;
IntPolyh_ListIteratorOfListOfCouples aIt(Couples);
for(; aIt.More(); aIt.Next())
{
Standard_Real cosa = Abs(aIt.Value().Angle());
if(cosa > eps) ++npara;
}
if (npara >= theMaillage->GetArrayOfTriangles(1).NbItems() ||
npara >= theMaillage->GetArrayOfTriangles(2).NbItems())
{
return Standard_False;
}
}
return Standard_True;
}

View File

@ -21,128 +21,191 @@
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <IntPolyh_ArrayOfPointNormal.hxx>
#include <IntPolyh_ArrayOfSectionLines.hxx>
#include <IntPolyh_ArrayOfTangentZones.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_Real.hxx>
#include <IntPolyh_PMaillageAffinage.hxx>
#include <IntPolyh_ListOfCouples.hxx>
#include <IntPolyh_PMaillageAffinage.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_Real.hxx>
class Adaptor3d_HSurface;
//! the main algorithm. Algorithm outputs are
//! lines and points like describe in the last
//! paragraph. The Algorithm provides direct access to
//! the elements of those lines and points. Other
//! classes of this package are for internal use and
//! only concern the algorithmic part.
class IntPolyh_Intersection
//! API algorithm for intersection of two surfaces by intersection
//! of their triangulations.
//!
//! Algorithm provides possibility to intersect surfaces as without
//! the precomputed sampling as with it.
//!
//! If the numbers of sampling points are not given, it will build the
//! net of 10x10 sampling points for each surface.
//!
//! The intersection is done inside constructors.
//! Before obtaining the results of intersection it is necessary to check
//! if intersection has been performed correctly. It can be done by calling
//! the *IsDone()* method.
//!
//! The results of intersection are the intersection lines and points.
class IntPolyh_Intersection
{
public:
DEFINE_STANDARD_ALLOC
//! Constructor
Standard_EXPORT IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_HSurface)& S2);
//! NbSU1 ... NbSV2 are used to compute the initial
//! samples of the iso parametric meshes on the
//! surfaces.
Standard_EXPORT IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1, const Standard_Integer NbSU1, const Standard_Integer NbSV1, const Handle(Adaptor3d_HSurface)& S2, const Standard_Integer NbSU2, const Standard_Integer NbSV2);
//! D1, D2 are used to compute the initial
//! samples of the iso parametric meshes on the
//! surfaces.
Standard_EXPORT IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1, const TColStd_Array1OfReal& anUpars1, const TColStd_Array1OfReal& aVpars1, const Handle(Adaptor3d_HSurface)& S2, const TColStd_Array1OfReal& anUpars2, const TColStd_Array1OfReal& aVpars2);
//! Compute the intersection.
public: //! @name Constructors
//! Constructor for intersection of two surfaces with default parameters.
//! Performs intersection.
Standard_EXPORT IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& theS1,
const Handle(Adaptor3d_HSurface)& theS2);
//! Constructor for intersection of two surfaces with the given
//! size of the sampling nets:
//! - <theNbSU1> x <theNbSV1> - for the first surface <theS1>;
//! - <theNbSU2> x <theNbSV2> - for the second surface <theS2>.
//! Performs intersection.
Standard_EXPORT IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& theS1,
const Standard_Integer theNbSU1,
const Standard_Integer theNbSV1,
const Handle(Adaptor3d_HSurface)& theS2,
const Standard_Integer theNbSU2,
const Standard_Integer theNbSV2);
//! Constructor for intersection of two surfaces with the precomputed sampling.
//! Performs intersection.
Standard_EXPORT IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& theS1,
const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const Handle(Adaptor3d_HSurface)& theS2,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2);
public: //! @name Getting the results
//! Returns state of the operation
Standard_Boolean IsDone() const
{
return myIsDone;
}
//! Returns the number of section lines
Standard_Integer NbSectionLines() const
{
return mySectionLines.NbItems();
}
//! Returns the number of points in the given line
Standard_Integer NbPointsInLine(const Standard_Integer IndexLine) const
{
return mySectionLines[IndexLine-1].NbStartPoints();
}
// Returns number of tangent zones
Standard_Integer NbTangentZones() const
{
return myTangentZones.NbItems();
}
//! Returns number of points in tangent zone
Standard_Integer NbPointsInTangentZone(const Standard_Integer) const
{
return 1;
}
//! Gets the parameters of the point in section line
Standard_EXPORT void GetLinePoint(const Standard_Integer IndexLine,
const Standard_Integer IndexPoint,
Standard_Real& x, Standard_Real& y, Standard_Real& z,
Standard_Real& u1, Standard_Real& v1,
Standard_Real& u2, Standard_Real& v2,
Standard_Real& incidence) const;
//! Gets the parameters of the point in tangent zone
Standard_EXPORT void GetTangentZonePoint(const Standard_Integer IndexLine,
const Standard_Integer IndexPoint,
Standard_Real& x, Standard_Real& y, Standard_Real& z,
Standard_Real& u1, Standard_Real& v1,
Standard_Real& u2, Standard_Real& v2) const;
private: //! @name Performing the intersection
//! Compute the intersection by first making the sampling of the surfaces.
Standard_EXPORT void Perform();
//! Compute the intersection.
Standard_EXPORT void Perform (const TColStd_Array1OfReal& Upars1, const TColStd_Array1OfReal& Vpars1, const TColStd_Array1OfReal& Upars2, const TColStd_Array1OfReal& Vpars2);
Standard_EXPORT Standard_Boolean IsDone() const;
Standard_EXPORT Standard_Integer NbSectionLines() const;
Standard_EXPORT Standard_Integer NbPointsInLine (const Standard_Integer IndexLine) const;
Standard_EXPORT void GetLinePoint (const Standard_Integer IndexLine, const Standard_Integer IndexPoint, Standard_Real& x, Standard_Real& y, Standard_Real& z, Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2, Standard_Real& incidence) const;
Standard_EXPORT Standard_Integer NbTangentZones() const;
Standard_EXPORT Standard_Integer NbPointsInTangentZone (const Standard_Integer IndexLine) const;
Standard_EXPORT void GetTangentZonePoint (const Standard_Integer IndexLine, const Standard_Integer IndexPoint, Standard_Real& x, Standard_Real& y, Standard_Real& z, Standard_Real& u1, Standard_Real& v1, Standard_Real& u2, Standard_Real& v2) const;
//! Compute the intersection on the precomputed sampling.
Standard_EXPORT void Perform(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2);
//! Performs the default (standard) intersection of the triangles
Standard_EXPORT Standard_Boolean PerformStd(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
IntPolyh_PMaillageAffinage& theMaillageS,
Standard_Integer& theNbCouples);
//! Performs the advanced intersection of the triangles - four intersection with
//! different shifts of the sampling points.
Standard_EXPORT Standard_Boolean PerformAdv(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
IntPolyh_PMaillageAffinage& theMaillageFF,
IntPolyh_PMaillageAffinage& theMaillageFR,
IntPolyh_PMaillageAffinage& theMaillageRF,
IntPolyh_PMaillageAffinage& theMaillageRR,
Standard_Integer& theNbCouples);
//! Performs the advanced intersection of the triangles.
Standard_EXPORT Standard_Boolean PerformMaillage(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
IntPolyh_PMaillageAffinage& theMaillage);
//! Performs the advanced intersection of the triangles.
Standard_EXPORT Standard_Boolean PerformMaillage(const TColStd_Array1OfReal& theUPars1,
const TColStd_Array1OfReal& theVPars1,
const TColStd_Array1OfReal& theUPars2,
const TColStd_Array1OfReal& theVPars2,
const Standard_Real theDeflTol1,
const Standard_Real theDeflTol2,
const IntPolyh_ArrayOfPointNormal& thePoints1,
const IntPolyh_ArrayOfPointNormal& thePoints2,
const Standard_Boolean theIsFirstFwd,
const Standard_Boolean theIsSecondFwd,
IntPolyh_PMaillageAffinage& theMaillage);
//! Clears the arrays from the duplicate couples, keeping only one instance of it.
Standard_EXPORT void MergeCouples(IntPolyh_ListOfCouples& theArrayFF,
IntPolyh_ListOfCouples& theArrayFR,
IntPolyh_ListOfCouples& theArrayRF,
IntPolyh_ListOfCouples& theArrayRR) const;
private: //! @name Fields
protected:
private:
//! Computes MaillageAffinage
Standard_EXPORT Standard_Boolean PerformMaillage (const Standard_Boolean isFirstFwd, const Standard_Boolean isSecondFwd, IntPolyh_PMaillageAffinage& MaillageS);
//! The method PerformMaillage(..) is used to compute MaillageAffinage. It is
//! called four times (two times for each surface) for creation of inscribed
//! and circumscribed mesh for each surface.
Standard_EXPORT Standard_Boolean PerformMaillage (IntPolyh_PMaillageAffinage& MaillageS);
//! Computes MaillageAffinage
Standard_EXPORT Standard_Boolean PerformMaillage (const Standard_Boolean isFirstFwd, const Standard_Boolean isSecondFwd, const TColStd_Array1OfReal& Upars1, const TColStd_Array1OfReal& Vpars1, const TColStd_Array1OfReal& Upars2, const TColStd_Array1OfReal& Vpars2, IntPolyh_PMaillageAffinage& MaillageS);
//! The method PerformMaillage(..) is used to compute MaillageAffinage. It is
//! called four times (two times for each surface) for creation of inscribed
//! and circumscribed mesh for each surface.
Standard_EXPORT Standard_Boolean PerformMaillage (const TColStd_Array1OfReal& Upars1, const TColStd_Array1OfReal& Vpars1, const TColStd_Array1OfReal& Upars2, const TColStd_Array1OfReal& Vpars2, IntPolyh_PMaillageAffinage& MaillageS);
//! This method analyzes arrays to find same couples. If some
//! are detected it leaves the couple in only one array
//! deleting from others.
Standard_EXPORT void MergeCouples (IntPolyh_ListOfCouples& anArrayFF, IntPolyh_ListOfCouples& anArrayFR, IntPolyh_ListOfCouples& anArrayRF, IntPolyh_ListOfCouples& anArrayRR) const;
//! Process default interference
Standard_EXPORT Standard_Boolean PerformStd (IntPolyh_PMaillageAffinage& MaillageS, Standard_Integer& NbCouples);
//! Process advanced interference
Standard_EXPORT Standard_Boolean PerformAdv (IntPolyh_PMaillageAffinage& MaillageFF, IntPolyh_PMaillageAffinage& MaillageFR, IntPolyh_PMaillageAffinage& MaillageRF, IntPolyh_PMaillageAffinage& MaillageRR, Standard_Integer& NbCouples);
//! Process default interference
Standard_EXPORT Standard_Boolean PerformStd (const TColStd_Array1OfReal& Upars1, const TColStd_Array1OfReal& Vpars1, const TColStd_Array1OfReal& Upars2, const TColStd_Array1OfReal& Vpars2, IntPolyh_PMaillageAffinage& MaillageS, Standard_Integer& NbCouples);
//! Process advanced interference
Standard_EXPORT Standard_Boolean PerformAdv (const TColStd_Array1OfReal& Upars1, const TColStd_Array1OfReal& Vpars1, const TColStd_Array1OfReal& Upars2, const TColStd_Array1OfReal& Vpars2, IntPolyh_PMaillageAffinage& MaillageFF, IntPolyh_PMaillageAffinage& MaillageFR, IntPolyh_PMaillageAffinage& MaillageRF, IntPolyh_PMaillageAffinage& MaillageRR, Standard_Integer& NbCouples);
Standard_Boolean done;
Standard_Integer nbsectionlines;
Standard_Integer nbtangentzones;
IntPolyh_ArrayOfSectionLines TSectionLines;
IntPolyh_ArrayOfTangentZones TTangentZones;
Standard_Integer myNbSU1;
Standard_Integer myNbSV1;
Standard_Integer myNbSU2;
Standard_Integer myNbSV2;
Handle(Adaptor3d_HSurface) mySurf1;
Handle(Adaptor3d_HSurface) mySurf2;
// Inputs
Handle(Adaptor3d_HSurface) mySurf1; //!< First surface
Handle(Adaptor3d_HSurface) mySurf2; //!< Second surface
Standard_Integer myNbSU1; //!< Number of samples in U direction for first surface
Standard_Integer myNbSV1; //!< Number of samples in V direction for first surface
Standard_Integer myNbSU2; //!< Number of samples in U direction for second surface
Standard_Integer myNbSV2; //!< Number of samples in V direction for second surface
// Results
Standard_Boolean myIsDone; //!< State of the operation
IntPolyh_ArrayOfSectionLines mySectionLines; //!< Section lines
IntPolyh_ArrayOfTangentZones myTangentZones; //!< Tangent zones
};
#endif // _IntPolyh_Intersection_HeaderFile

View File

@ -1,317 +0,0 @@
// Created on: 2005-09-26
// Created by: Igor FEOKTISTOV
// Copyright (c) 2005-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 <Adaptor3d_HSurface.hxx>
#include <IntPolyh_ListOfCouples.hxx>
#include <IntPolyh_Couple.hxx>
#include <IntPolyh_Intersection.hxx>
#include <IntPolyh_MaillageAffinage.hxx>
#include <IntPolyh_PMaillageAffinage.hxx>
#include <IntPolyh_Triangle.hxx>
Standard_Integer MYPRINT1 = 0;
//=======================================================================
//function : IntPolyh_Intersection
//purpose :
//=======================================================================
IntPolyh_Intersection::IntPolyh_Intersection(const Handle(Adaptor3d_HSurface)& S1,
const TColStd_Array1OfReal& Upars1,
const TColStd_Array1OfReal& Vpars1,
const Handle(Adaptor3d_HSurface)& S2,
const TColStd_Array1OfReal& Upars2,
const TColStd_Array1OfReal& Vpars2)
{
myNbSU1 = Upars1.Length();
myNbSV1 = Vpars1.Length();
myNbSU2 = Upars2.Length();
myNbSV2 = Vpars2.Length();
mySurf1 = S1;
mySurf2 = S2;
done = Standard_False;
TSectionLines.Init(1000);
TTangentZones.Init(10000);
Perform(Upars1, Vpars1, Upars2, Vpars2);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void IntPolyh_Intersection::Perform(const TColStd_Array1OfReal& Upars1,
const TColStd_Array1OfReal& Vpars1,
const TColStd_Array1OfReal& Upars2,
const TColStd_Array1OfReal& Vpars2) {
done = Standard_True;
Standard_Boolean isStdDone = Standard_False;
Standard_Boolean isAdvDone = Standard_False;
Standard_Integer nbCouplesStd = 0;
Standard_Integer nbCouplesAdv = 0;
IntPolyh_PMaillageAffinage aPMaillageStd = 0;
IntPolyh_PMaillageAffinage aPMaillageFF = 0;
IntPolyh_PMaillageAffinage aPMaillageFR = 0;
IntPolyh_PMaillageAffinage aPMaillageRF = 0;
IntPolyh_PMaillageAffinage aPMaillageRR = 0;
isStdDone = PerformStd( Upars1, Vpars1, Upars2, Vpars2,
aPMaillageStd,nbCouplesStd);
// default interference done well, use it
if(isStdDone && nbCouplesStd > 10) {
aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
}
// default interference done, but too few interferences foud;
// use advanced interference
else if(isStdDone && nbCouplesStd <= 10) {
isAdvDone = PerformAdv( Upars1, Vpars1, Upars2, Vpars2,
aPMaillageFF,aPMaillageFR,aPMaillageRF,
aPMaillageRR,nbCouplesAdv);
// advanced interference found
if(isAdvDone && nbCouplesAdv > 0) {
aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
}
else {
// use result of default
if(nbCouplesStd > 0)
aPMaillageStd->StartPointsChain(TSectionLines, TTangentZones);
}
}
// default interference faild, use advanced
else {
// isAdvDone = PerformAdv(aPMaillageFF,aPMaillageFR,aPMaillageRF,aPMaillageRR,nbCouplesAdv);
// if(isAdvDone && nbCouplesAdv > 0) {cout << "4adv done, nbc: " << nbCouplesAdv << endl;
// aPMaillageFF->StartPointsChain(TSectionLines,TTangentZones);
// aPMaillageFR->StartPointsChain(TSectionLines,TTangentZones);
// aPMaillageRF->StartPointsChain(TSectionLines,TTangentZones);
// aPMaillageRR->StartPointsChain(TSectionLines,TTangentZones);
// }
}
// accept result
nbsectionlines = TSectionLines.NbItems();
nbtangentzones = TTangentZones.NbItems();
// clean up
if(aPMaillageStd) delete aPMaillageStd;
if(aPMaillageFF) delete aPMaillageFF;
if(aPMaillageFR) delete aPMaillageFR;
if(aPMaillageRF) delete aPMaillageRF;
if(aPMaillageRR) delete aPMaillageRR;
// verify
if(!isStdDone && !isAdvDone)
done = Standard_False;
}
//=======================================================================
//function : PerformMaillage
//purpose : Computes MaillageAffinage
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformMaillage(const Standard_Boolean isFirstFwd,
const Standard_Boolean isSecondFwd,
const TColStd_Array1OfReal& Upars1,
const TColStd_Array1OfReal& Vpars1,
const TColStd_Array1OfReal& Upars2,
const TColStd_Array1OfReal& Vpars2,
IntPolyh_PMaillageAffinage &theMaillageS)
{
theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, Upars1.Length(), Vpars1.Length(),
mySurf2, Upars2.Length(), Vpars2.Length(),
MYPRINT1);
theMaillageS->FillArrayOfPnt(1, isFirstFwd, Upars1, Vpars1);
theMaillageS->FillArrayOfPnt(2, isSecondFwd, Upars2, Vpars2);
Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
xx0, yy0, zz0, xx1, yy1, zz1);
theMaillageS->FillArrayOfTriangles(1);
theMaillageS->FillArrayOfTriangles(2);
theMaillageS->FillArrayOfEdges(1);
theMaillageS->FillArrayOfEdges(2);
theMaillageS->TrianglesDeflectionsRefinementBSB();
Standard_Integer FinTTC = theMaillageS->TriangleCompare();
// if too many intersections, consider surfaces parallel (eap)
// test for parallel surf
if(FinTTC > 200) {
const Standard_Real eps = .996; //~ cos of 5deg.
IntPolyh_ListOfCouples& Couples = theMaillageS->GetCouples();
Standard_Integer npara = 0;
IntPolyh_ListIteratorOfListOfCouples aIt(Couples);
for(; aIt.More(); aIt.Next()) {
Standard_Real cosa = Abs(aIt.Value().Angle());
if(cosa > eps) ++npara;
}
if(npara >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
npara >= theMaillageS->GetArrayOfTriangles(2).NbItems() ) {
return Standard_False;
}
}
return Standard_True;
}
//=======================================================================
//function : PerformMaillage
//purpose : Computes MaillageAffinage
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformMaillage(const TColStd_Array1OfReal& Upars1,
const TColStd_Array1OfReal& Vpars1,
const TColStd_Array1OfReal& Upars2,
const TColStd_Array1OfReal& Vpars2,
IntPolyh_PMaillageAffinage &theMaillageS)
{
theMaillageS = new IntPolyh_MaillageAffinage(mySurf1, Upars1.Length(), Vpars1.Length(),
mySurf2, Upars2.Length(), Vpars2.Length(),
MYPRINT1);
theMaillageS->FillArrayOfPnt(1, Upars1, Vpars1);
theMaillageS->FillArrayOfPnt(2, Upars2, Vpars2);
Standard_Real xx0,yy0,zz0,xx1,yy1,zz1;
theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
xx0, yy0, zz0, xx1, yy1, zz1);
theMaillageS->FillArrayOfTriangles(1);
theMaillageS->FillArrayOfTriangles(2);
theMaillageS->FillArrayOfEdges(1);
theMaillageS->FillArrayOfEdges(2);
theMaillageS->TrianglesDeflectionsRefinementBSB();
Standard_Integer FinTTC = theMaillageS->TriangleCompare();
if( FinTTC == 0 ) {
Standard_Boolean myZone = Standard_True;
theMaillageS->SetEnlargeZone( myZone );
theMaillageS->FillArrayOfPnt(1);
theMaillageS->FillArrayOfPnt(2);
theMaillageS->CommonBox(theMaillageS->GetBox(1), theMaillageS->GetBox(2),
xx0, yy0, zz0, xx1, yy1, zz1);
theMaillageS->FillArrayOfTriangles(1);
theMaillageS->FillArrayOfTriangles(2);
theMaillageS->FillArrayOfEdges(1);
theMaillageS->FillArrayOfEdges(2);
theMaillageS->TrianglesDeflectionsRefinementBSB();
FinTTC = theMaillageS->TriangleCompare();
myZone = Standard_False;
theMaillageS->SetEnlargeZone( myZone );
}
// if too many intersections, consider surfaces parallel (eap)
//IFV test for parallel surf
if(FinTTC > 200) {
const Standard_Real eps = .996; //~ cos of 5deg.
IntPolyh_ListOfCouples& Couples = theMaillageS->GetCouples();
Standard_Integer npara = 0;
IntPolyh_ListIteratorOfListOfCouples aIt(Couples);
for(; aIt.More(); aIt.Next()) {
Standard_Real cosa = Abs(aIt.Value().Angle());
if(cosa > eps) ++npara;
}
if(npara >= theMaillageS->GetArrayOfTriangles(1).NbItems() ||
npara >= theMaillageS->GetArrayOfTriangles(2).NbItems() ) {
return Standard_False;
}
}
return Standard_True;
}
//=======================================================================
//function : PerformAdv
//purpose :
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformAdv(const TColStd_Array1OfReal& Upars1,
const TColStd_Array1OfReal& Vpars1,
const TColStd_Array1OfReal& Upars2,
const TColStd_Array1OfReal& Vpars2,
IntPolyh_PMaillageAffinage& MaillageFF,
IntPolyh_PMaillageAffinage& MaillageFR,
IntPolyh_PMaillageAffinage& MaillageRF,
IntPolyh_PMaillageAffinage& MaillageRR,
Standard_Integer& NbCouples)
{
Standard_Boolean isdone = Standard_True;
NbCouples = 0;
if(!PerformMaillage(Standard_True,Standard_False,
Upars1, Vpars1, Upars2, Vpars2,
MaillageFR) ||
!PerformMaillage(Standard_False,Standard_True,
Upars1, Vpars1, Upars2, Vpars2,
MaillageRF) ||
!PerformMaillage(Standard_True,Standard_True,
Upars1, Vpars1, Upars2, Vpars2,
MaillageFF) ||
!PerformMaillage(Standard_False,Standard_False,
Upars1, Vpars1, Upars2, Vpars2,
MaillageRR) )
isdone = Standard_False;
if(isdone) {
NbCouples = MaillageFF->GetCouples().Extent() +
MaillageFR->GetCouples().Extent() +
MaillageRF->GetCouples().Extent() +
MaillageRR->GetCouples().Extent();
if(NbCouples > 0)
MergeCouples(MaillageFF->GetCouples(),MaillageFR->GetCouples(),
MaillageRF->GetCouples(),MaillageRR->GetCouples());
}
return isdone;
}
//=======================================================================
//function : PerformStd
//purpose :
//=======================================================================
Standard_Boolean IntPolyh_Intersection::PerformStd(const TColStd_Array1OfReal& Upars1,
const TColStd_Array1OfReal& Vpars1,
const TColStd_Array1OfReal& Upars2,
const TColStd_Array1OfReal& Vpars2,
IntPolyh_PMaillageAffinage& MaillageS,
Standard_Integer& NbCouples)
{
Standard_Boolean isdone = PerformMaillage(Upars1, Vpars1, Upars2, Vpars2,
MaillageS);
NbCouples = (isdone) ? (MaillageS->GetCouples().Extent()) : 0;
return isdone;
}

View File

@ -29,7 +29,6 @@
#include <Bnd_HArray1OfBox.hxx>
#include <gp.hxx>
#include <gp_Pnt.hxx>
#include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
#include <IntPolyh_ListOfCouples.hxx>
#include <IntPolyh_Couple.hxx>
#include <IntPolyh_Edge.hxx>
@ -37,6 +36,7 @@
#include <IntPolyh_Point.hxx>
#include <IntPolyh_SectionLine.hxx>
#include <IntPolyh_StartPoint.hxx>
#include <IntPolyh_Tools.hxx>
#include <IntPolyh_Triangle.hxx>
#include <Precision.hxx>
#include <TColStd_Array1OfInteger.hxx>
@ -131,12 +131,6 @@ static
const Standard_Integer aIsoDirection,
Standard_Integer& aI1,
Standard_Integer& aI2);
static
void EnlargeZone(const Handle(Adaptor3d_HSurface)& MaSurface,
Standard_Real &u0,
Standard_Real &u1,
Standard_Real &v0,
Standard_Real &v1);
//=======================================================================
//class : IntPolyh_BoxBndTreeSelector
@ -184,6 +178,7 @@ static
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
// 1. Fill the tree with the boxes of the triangles from second surface
Standard_Integer i, aNbT2 = theTriangles2.NbItems();
Standard_Boolean bAdded = Standard_False;
for (i = 0; i < aNbT2; ++i) {
IntPolyh_Triangle& aT = theTriangles2[i];
if (!aT.IsIntersectionPossible() || aT.IsDegenerated()) {
@ -192,8 +187,13 @@ static
//
const Bnd_Box& aBox = aT.BoundingBox(thePoints2);
aTreeFiller.Add(i, aBox);
bAdded = Standard_True;
}
//
if (!bAdded)
// Intersection is not possible for all triangles in theTriangles2
return;
// 2. Shake the tree filler
aTreeFiller.Fill();
//
@ -245,8 +245,6 @@ IntPolyh_MaillageAffinage::IntPolyh_MaillageAffinage
FlecheMax2(0.0),
FlecheMin1(0.0),
FlecheMin2(0.0),
FlecheMoy1(0.0),
FlecheMoy2(0.0),
myEnlargeZone(Standard_False)
{
}
@ -273,11 +271,23 @@ IntPolyh_MaillageAffinage::IntPolyh_MaillageAffinage
FlecheMax2(0.0),
FlecheMin1(0.0),
FlecheMin2(0.0),
FlecheMoy1(0.0),
FlecheMoy2(0.0),
myEnlargeZone(Standard_False)
{
}
//=======================================================================
//function : MakeSampling
//purpose :
//=======================================================================
void IntPolyh_MaillageAffinage::MakeSampling(const Standard_Integer SurfID,
TColStd_Array1OfReal& theUPars,
TColStd_Array1OfReal& theVPars)
{
if (SurfID == 1)
IntPolyh_Tools::MakeSampling(MaSurface1, NbSamplesU1, NbSamplesV1, myEnlargeZone, theUPars, theVPars);
else
IntPolyh_Tools::MakeSampling(MaSurface2, NbSamplesU2, NbSamplesV2, myEnlargeZone, theUPars, theVPars);
}
//=======================================================================
//function : FillArrayOfPnt
//purpose : Compute points on one surface and fill an array of points
@ -285,47 +295,10 @@ IntPolyh_MaillageAffinage::IntPolyh_MaillageAffinage
void IntPolyh_MaillageAffinage::FillArrayOfPnt
(const Standard_Integer SurfID)
{
Standard_Integer NbSamplesU, NbSamplesV, i, aNbSamplesU1, aNbSamplesV1;
Standard_Real u0, u1, v0, v1, aU, aV, dU, dV;
//
const Handle(Adaptor3d_HSurface)& MaSurface=(SurfID==1)? MaSurface1 : MaSurface2;
NbSamplesU=(SurfID==1)? NbSamplesU1:NbSamplesU2;
NbSamplesV=(SurfID==1)? NbSamplesV1:NbSamplesV2;
//
u0 = (MaSurface)->FirstUParameter();
u1 = (MaSurface)->LastUParameter();
v0 = (MaSurface)->FirstVParameter();
v1 = (MaSurface)->LastVParameter();
if(myEnlargeZone) {
EnlargeZone(MaSurface, u0, u1, v0, v1);
}
//
TColStd_Array1OfReal aUpars(1, NbSamplesU);
TColStd_Array1OfReal aVpars(1, NbSamplesV);
//
aNbSamplesU1=NbSamplesU-1;
aNbSamplesV1=NbSamplesV-1;
//
dU=(u1-u0)/Standard_Real(aNbSamplesU1);
dV=(v1-v0)/Standard_Real(aNbSamplesV1);
//
for (i=0; i<NbSamplesU; ++i) {
aU=u0+i*dU;
if (i==aNbSamplesU1) {
aU=u1;
}
aUpars.SetValue(i+1, aU);
}
//
for (i=0; i<NbSamplesV; ++i) {
aV=v0+i*dV;
if (i==aNbSamplesV1) {
aV=v1;
}
aVpars.SetValue(i+1, aV);
}
//
// Make sampling
TColStd_Array1OfReal aUpars, aVpars;
MakeSampling(SurfID, aUpars, aVpars);
// Fill array of points
FillArrayOfPnt(SurfID, aUpars, aVpars);
}
//=======================================================================
@ -337,47 +310,11 @@ void IntPolyh_MaillageAffinage::FillArrayOfPnt
(const Standard_Integer SurfID,
const Standard_Boolean isShiftFwd)
{
Standard_Integer NbSamplesU, NbSamplesV, i, aNbSamplesU1, aNbSamplesV1;
Standard_Real u0, u1, v0, v1, aU, aV, dU, dV;
const Handle(Adaptor3d_HSurface)& MaSurface=(SurfID==1)? MaSurface1 : MaSurface2;
NbSamplesU=(SurfID==1)? NbSamplesU1:NbSamplesU2;
NbSamplesV=(SurfID==1)? NbSamplesV1:NbSamplesV2;
u0 = (MaSurface)->FirstUParameter();
u1 = (MaSurface)->LastUParameter();
v0 = (MaSurface)->FirstVParameter();
v1 = (MaSurface)->LastVParameter();
if(myEnlargeZone) {
EnlargeZone(MaSurface, u0, u1, v0, v1);
}
//
TColStd_Array1OfReal aUpars(1, NbSamplesU);
TColStd_Array1OfReal aVpars(1, NbSamplesV);
//
aNbSamplesU1=NbSamplesU-1;
aNbSamplesV1=NbSamplesV-1;
//
dU=(u1-u0)/Standard_Real(aNbSamplesU1);
dV=(v1-v0)/Standard_Real(aNbSamplesV1);
//
for (i=0; i<NbSamplesU; ++i) {
aU=u0+i*dU;
if (i==aNbSamplesU1) {
aU=u1;
}
aUpars.SetValue(i+1, aU);
}
//
for (i=0; i<NbSamplesV; ++i) {
aV=v0+i*dV;
if (i==aNbSamplesV1) {
aV=v1;
}
aVpars.SetValue(i+1, aV);
}
//
FillArrayOfPnt(SurfID, isShiftFwd, aUpars, aVpars);
// Make sampling
TColStd_Array1OfReal aUpars, aVpars;
MakeSampling(SurfID, aUpars, aVpars);
// Fill array of points
FillArrayOfPnt(SurfID, isShiftFwd, aUpars, aVpars);
}
//=======================================================================
//function : FillArrayOfPnt
@ -386,7 +323,8 @@ void IntPolyh_MaillageAffinage::FillArrayOfPnt
void IntPolyh_MaillageAffinage::FillArrayOfPnt
(const Standard_Integer SurfID,
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars)
const TColStd_Array1OfReal& Vpars,
const Standard_Real *theDeflTol)
{
Standard_Boolean bDegI, bDeg;
Standard_Integer aNbU, aNbV, iCnt, i, j;
@ -432,10 +370,8 @@ void IntPolyh_MaillageAffinage::FillArrayOfPnt
//
TPoints.SetNbItems(iCnt);
//
IntCurveSurface_ThePolyhedronOfHInter polyhedron(aS, Upars, Vpars);
//
aTol=polyhedron.DeflectionOverEstimation();
aTol*=1.2;
aTol = !theDeflTol ? IntPolyh_Tools::ComputeDeflection(aS, Upars, Vpars) : *theDeflTol;
aTol *= 1.2;
Standard_Real a1,a2,a3,b1,b2,b3;
//
@ -444,90 +380,103 @@ void IntPolyh_MaillageAffinage::FillArrayOfPnt
aBox.Enlarge(MyTolerance);
}
//=======================================================================
//function : FillArrayOfPnt
//purpose :
//=======================================================================
void IntPolyh_MaillageAffinage::FillArrayOfPnt(const Standard_Integer SurfID,
const Standard_Boolean isShiftFwd,
const IntPolyh_ArrayOfPointNormal& thePointsNorm,
const TColStd_Array1OfReal& theUPars,
const TColStd_Array1OfReal& theVPars,
const Standard_Real theDeflTol)
{
Handle(Adaptor3d_HSurface) aS = (SurfID == 1) ? MaSurface1 : MaSurface2;
IntPolyh_ArrayOfPoints& TPoints = (SurfID == 1) ? TPoints1 : TPoints2;
Standard_Integer aNbU = (SurfID == 1) ? NbSamplesU1 : NbSamplesU2;
Standard_Integer aNbV = (SurfID == 1) ? NbSamplesV1 : NbSamplesV2;
Bnd_Box& aBox = (SurfID==1) ? MyBox1 : MyBox2;
Standard_Integer aJD1(0), aJD2(0), aID1(0), aID2(0);
DegeneratedIndex(theVPars, aNbV, aS, 1, aJD1, aJD2);
if (!(aJD1 || aJD2))
DegeneratedIndex(theUPars, aNbU, aS, 2, aID1, aID2);
Standard_Boolean bDegI, bDeg;
Standard_Integer iCnt(0), i, j;
Standard_Real aX, aY, aZ, aU, aV;
TPoints.Init(thePointsNorm.NbItems());
for (i = 1; i <= aNbU; ++i)
{
aU = theUPars(i);
bDegI = (aID1 == i || aID2 == i);
for (j = 1; j <= aNbV; ++j)
{
aV = theVPars(j);
const IntPolyh_PointNormal& aPN = thePointsNorm.Value(iCnt);
gp_Vec aNorm = aPN.Normal.Multiplied(1.5*theDeflTol);
if (!isShiftFwd)
aNorm.Reverse();
gp_Pnt aP = aPN.Point.Translated(aNorm);
IntPolyh_Point& aIP = TPoints[iCnt];
aP.Coord(aX, aY, aZ);
aIP.Set(aX, aY, aZ, aU, aV);
bDeg = bDegI || (aJD1 == j || aJD2 == j);
if (bDeg)
aIP.SetDegenerated(bDeg);
++iCnt;
aBox.Add(aP);
}
}
TPoints.SetNbItems(iCnt);
// Update box
Standard_Real Tol = theDeflTol*1.2;
Standard_Real a1,a2,a3,b1,b2,b3;
aBox.Get(a1,a2,a3,b1,b2,b3);
aBox.Update(a1-Tol,a2-Tol,a3-Tol,b1+Tol,b2+Tol,b3+Tol);
aBox.Enlarge(MyTolerance);
}
//=======================================================================
//function : FillArrayOfPnt
//purpose : Compute points on one surface and fill an array of points
// REMPLISSAGE DU TABLEAU DE POINTS
//=======================================================================
void IntPolyh_MaillageAffinage::FillArrayOfPnt
(const Standard_Integer SurfID,
const Standard_Boolean isShiftFwd,
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars)
const TColStd_Array1OfReal& Vpars,
const Standard_Real *theDeflTol)
{
Standard_Boolean bDegI, bDeg;
Standard_Integer aNbU, aNbV, iCnt, i, j;
Standard_Integer aID1, aID2, aJD1, aJD2;
Standard_Real Tol, resol, aU, aV, aMag;
Standard_Real aX, aY, aZ;
gp_Pnt aP;
gp_Vec aDU, aDV, aNorm;
//
aNbU=(SurfID==1)? NbSamplesU1:NbSamplesU2;
aNbV=(SurfID==1)? NbSamplesV1:NbSamplesV2;
Bnd_Box& aBox = (SurfID==1) ? MyBox1 : MyBox2;
Handle(Adaptor3d_HSurface) aS=(SurfID==1)? MaSurface1:MaSurface2;
IntPolyh_ArrayOfPoints &TPoints=(SurfID==1)? TPoints1:TPoints2;
//
resol = gp::Resolution();
//
IntCurveSurface_ThePolyhedronOfHInter polyhedron(aS, Upars, Vpars);
Tol=polyhedron.DeflectionOverEstimation();
aJD1=0;
aJD2=0;
aID1=0;
aID2=0;
DegeneratedIndex(Vpars, aNbV, aS, 1, aJD1, aJD2);
if (!(aJD1 || aJD2)) {
DegeneratedIndex(Upars, aNbU, aS, 2, aID1, aID2);
}
//
TPoints.Init(aNbU*aNbV);
iCnt=0;
for(i=1; i<=aNbU; ++i){
bDegI=(aID1==i || aID2==i);
aU = Upars(i);
for(j=1; j<=aNbV; ++j){
aV = Vpars(j);
aS->D1(aU, aV, aP, aDU, aDV);
aNorm = aDU.Crossed(aDV);
aMag = aNorm.Magnitude();
if (aMag > resol) {
aNorm /= aMag;
aNorm.Multiply(Tol*1.5);
//
if (isShiftFwd) {
aP.Translate(aNorm);
}
else{
aP.Translate(aNorm.Reversed());
}
}
IntPolyh_Point& aIP=TPoints[iCnt];
aP.Coord(aX, aY, aZ);
aIP.Set(aX, aY, aZ, aU, aV);
//
bDeg=bDegI || (aJD1==j || aJD2==j);
if (bDeg) {
aIP.SetDegenerated(bDeg);
}
++iCnt;
aBox.Add(aP);
}
}
//
TPoints.SetNbItems(iCnt);
//
Tol*=1.2;
//
Standard_Real a1,a2,a3,b1,b2,b3;
//
aBox.Get(a1,a2,a3,b1,b2,b3);
aBox.Update(a1-Tol,a2-Tol,a3-Tol,b1+Tol,b2+Tol,b3+Tol);
aBox.Enlarge(MyTolerance);
Handle(Adaptor3d_HSurface) aS = (SurfID == 1) ? MaSurface1 : MaSurface2;
// Compute the tolerance
Standard_Real aTol = theDeflTol != NULL ? * theDeflTol :
IntPolyh_Tools::ComputeDeflection(aS, Upars, Vpars);
// Fill array of point normal
IntPolyh_ArrayOfPointNormal aPoints;
IntPolyh_Tools::FillArrayOfPointNormal(aS, Upars, Vpars, aPoints);
// Fill array of points
FillArrayOfPnt(1, isShiftFwd, aPoints, Upars, Vpars, aTol);
}
//=======================================================================
//function : CommonBox
//purpose :
//=======================================================================
void IntPolyh_MaillageAffinage::CommonBox()
{
Standard_Real XMin, YMin, ZMin, XMax, YMax, ZMax;
CommonBox(GetBox(1), GetBox(2), XMin, YMin, ZMin, XMax, YMax, ZMax);
}
//=======================================================================
//function : CommonBox
//purpose : Compute the common box witch is the intersection
@ -939,12 +888,10 @@ void IntPolyh_MaillageAffinage::ComputeDeflections
IntPolyh_ArrayOfPoints &TPoints=(SurfID==1)? TPoints1:TPoints2;
IntPolyh_ArrayOfTriangles &TTriangles=(SurfID==1)? TTriangles1:TTriangles2;
Standard_Real &FlecheMin=(SurfID==1)? FlecheMin1:FlecheMin2;
Standard_Real &FlecheMoy=(SurfID==1)? FlecheMoy1:FlecheMoy2;
Standard_Real &FlecheMax=(SurfID==1)? FlecheMax1:FlecheMax2;
FlecheMax=-RealLast();
FlecheMin=RealLast();
FlecheMoy=0.0;
const Standard_Integer FinTT = TTriangles.NbItems();
for(Standard_Integer i = 0; i < FinTT; i++) {
@ -2878,7 +2825,7 @@ IntPolyh_ListOfCouples &IntPolyh_MaillageAffinage::GetCouples()
//function : SetEnlargeZone
//purpose :
//=======================================================================
void IntPolyh_MaillageAffinage::SetEnlargeZone(Standard_Boolean& EnlargeZone)
void IntPolyh_MaillageAffinage::SetEnlargeZone(const Standard_Boolean EnlargeZone)
{
myEnlargeZone = EnlargeZone;
}
@ -3030,29 +2977,3 @@ Standard_Boolean IsDegenerated(const Handle(Adaptor3d_HSurface)& aS,
//
return bRet;
}
//=======================================================================
//function : EnlargeZone
//purpose :
//=======================================================================
void EnlargeZone(const Handle(Adaptor3d_HSurface)& MaSurface,
Standard_Real &u0,
Standard_Real &u1,
Standard_Real &v0,
Standard_Real &v1)
{
if(MaSurface->GetType() == GeomAbs_BSplineSurface ||
MaSurface->GetType() == GeomAbs_BezierSurface) {
if((!MaSurface->IsUClosed() && !MaSurface->IsUPeriodic()) &&
(Abs(u0) < 1.e+100 && Abs(u1) < 1.e+100) ) {
Standard_Real delta_u = 0.01*Abs(u1 - u0);
u0 -= delta_u;
u1 += delta_u;
}
if((!MaSurface->IsVClosed() && !MaSurface->IsVPeriodic()) &&
(Abs(v0) < 1.e+100 && Abs(v1) < 1.e+100) ) {
Standard_Real delta_v = 0.01*Abs(v1 - v0);
v0 -= delta_v;
v1 += delta_v;
}
}
}

View File

@ -30,6 +30,7 @@
#include <IntPolyh_ListOfCouples.hxx>
#include <Standard_Boolean.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <IntPolyh_ArrayOfPointNormal.hxx>
#include <IntPolyh_ArrayOfSectionLines.hxx>
#include <IntPolyh_ArrayOfTangentZones.hxx>
class Adaptor3d_HSurface;
@ -40,8 +41,9 @@ class IntPolyh_Triangle;
class IntPolyh_SectionLine;
//! Provide the algorythms used in the package
class IntPolyh_MaillageAffinage
//! Low-level algorithm to compute intersection of the surfaces
//! by computing the intersection of their triangulations.
class IntPolyh_MaillageAffinage
{
public:
@ -52,7 +54,14 @@ public:
Standard_EXPORT IntPolyh_MaillageAffinage(const Handle(Adaptor3d_HSurface)& S1, const Handle(Adaptor3d_HSurface)& S2, const Standard_Integer PRINT);
//! Compute points on one surface and fill an array of points;
//! Makes the sampling of the surface -
//! Fills the arrays with the parametric values of the sampling points (triangulation nodes).
Standard_EXPORT void MakeSampling (const Standard_Integer SurfID,
TColStd_Array1OfReal& theUPars,
TColStd_Array1OfReal& theVPars);
//! Computes points on one surface and fills an array of points;
//! standard (default) method
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID);
@ -63,11 +72,16 @@ public:
//! direction) is defined by isShiftFwd flag.
//! Compute points on one surface and fill an array of points;
//! advanced method
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID, const Standard_Boolean isShiftFwd);
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID,
const Standard_Boolean isShiftFwd);
//! Compute points on one surface and fill an array of points;
//! If given, <theDeflTol> is the deflection tolerance of the given sampling.
//! standard (default) method
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID, const TColStd_Array1OfReal& Upars, const TColStd_Array1OfReal& Vpars);
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID,
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars,
const Standard_Real *theDeflTol = NULL);
//! isShiftFwd flag is added. The purpose is to define shift
//! of points along normal to the surface in this point. The
@ -75,9 +89,26 @@ public:
//! The direction (forward or reversed regarding to normal
//! direction) is defined by isShiftFwd flag.
//! Compute points on one surface and fill an array of points;
//! If given, <theDeflTol> is the deflection tolerance of the given sampling.
//! advanced method
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID, const Standard_Boolean isShiftFwd, const TColStd_Array1OfReal& Upars, const TColStd_Array1OfReal& Vpars);
Standard_EXPORT void FillArrayOfPnt (const Standard_Integer SurfID,
const Standard_Boolean isShiftFwd,
const TColStd_Array1OfReal& Upars,
const TColStd_Array1OfReal& Vpars,
const Standard_Real *theDeflTol = NULL);
//! Fills the array of points for the surface taking into account the shift
Standard_EXPORT void FillArrayOfPnt(const Standard_Integer SurfID,
const Standard_Boolean isShiftFwd,
const IntPolyh_ArrayOfPointNormal& thePoints,
const TColStd_Array1OfReal& theUPars,
const TColStd_Array1OfReal& theVPars,
const Standard_Real theDeflTol);
//! Looks for the common box of the surfaces and marks the points
//! of the surfaces inside that common box for possible intersection
Standard_EXPORT void CommonBox();
//! Compute the common box witch is the intersection
//! of the two bounding boxes, and mark the points of
//! the two surfaces that are inside.
@ -156,7 +187,7 @@ public:
//! This method returns list of couples of contact triangles.
Standard_EXPORT IntPolyh_ListOfCouples& GetCouples();
Standard_EXPORT void SetEnlargeZone (Standard_Boolean& EnlargeZone);
Standard_EXPORT void SetEnlargeZone (const Standard_Boolean EnlargeZone);
Standard_EXPORT Standard_Boolean GetEnlargeZone() const;
@ -173,7 +204,6 @@ protected:
private:
Handle(Adaptor3d_HSurface) MaSurface1;
Handle(Adaptor3d_HSurface) MaSurface2;
Bnd_Box MyBox1;
@ -186,8 +216,6 @@ private:
Standard_Real FlecheMax2;
Standard_Real FlecheMin1;
Standard_Real FlecheMin2;
Standard_Real FlecheMoy1;
Standard_Real FlecheMoy2;
// For the arrays of Points, Edges and Triangles we need instant access to the items.
// Moreover, we might add new items during refinement process in case the deflection
// is too big, thus the vectors should be used.

View File

@ -0,0 +1,198 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2017 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 <IntPolyh_Tools.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <Precision.hxx>
#include <IntCurveSurface_ThePolyhedronOfHInter.hxx>
//=======================================================================
//function : IsEnlargePossible
//purpose :
//=======================================================================
void IntPolyh_Tools::IsEnlargePossible(const Handle(Adaptor3d_HSurface)& theSurf,
Standard_Boolean& theUEnlarge,
Standard_Boolean& theVEnlarge)
{
theUEnlarge = Standard_False;
theVEnlarge = Standard_False;
// In the context of IntPolyh_Intersection only BSpline and Bezier surfaces
// should be enlarged
if (theSurf->GetType() == GeomAbs_BSplineSurface ||
theSurf->GetType() == GeomAbs_BezierSurface)
{
// Check U periodicity and closeness
if (!theSurf->IsUClosed() && !theSurf->IsUPeriodic())
{
// Check that surface is not infinite in U direction
if (!Precision::IsInfinite(theSurf->FirstUParameter()) &&
!Precision::IsInfinite(theSurf->LastUParameter()))
{
theUEnlarge = Standard_True;
}
}
// Check V periodicity and closeness
if (!theSurf->IsVClosed() && !theSurf->IsVPeriodic())
{
// Check that surface is not infinite in V direction
if (!Precision::IsInfinite(theSurf->FirstVParameter()) &&
!Precision::IsInfinite(theSurf->LastVParameter()))
{
theVEnlarge = Standard_True;
}
}
}
}
//=======================================================================
//function : EnlargeZone
//purpose : Enlarges the sampling zone of the surface
//=======================================================================
static void EnlargeZone(const Handle(Adaptor3d_HSurface)& theSurf,
Standard_Real &u0,
Standard_Real &u1,
Standard_Real &v0,
Standard_Real &v1)
{
Standard_Boolean isToEnlargeU, isToEnlargeV;
IntPolyh_Tools::IsEnlargePossible(theSurf, isToEnlargeU, isToEnlargeV);
// Enlarge U
if (isToEnlargeU)
{
Standard_Real delta_u = 0.01*Abs(u1 - u0);
u0 -= delta_u;
u1 += delta_u;
}
if (isToEnlargeV)
{
Standard_Real delta_v = 0.01*Abs(v1 - v0);
v0 -= delta_v;
v1 += delta_v;
}
}
//=======================================================================
//function : MakeSampling
//purpose :
//=======================================================================
void IntPolyh_Tools::MakeSampling(const Handle(Adaptor3d_HSurface)& theSurf,
const Standard_Integer theNbSU,
const Standard_Integer theNbSV,
const Standard_Boolean theEnlargeZone,
TColStd_Array1OfReal& theUPars,
TColStd_Array1OfReal& theVPars)
{
// Resize arrays
theUPars.Resize(1, theNbSU, Standard_False);
theVPars.Resize(1, theNbSV, Standard_False);
//
Standard_Real u0, u1, v0, v1;
u0 = theSurf->FirstUParameter();
u1 = theSurf->LastUParameter();
v0 = theSurf->FirstVParameter();
v1 = theSurf->LastVParameter();
// Enlarge surface intersection zone if necessary
if (theEnlargeZone)
EnlargeZone(theSurf, u0, u1, v0, v1);
Standard_Integer aNbSamplesU1 = theNbSU - 1;
Standard_Integer aNbSamplesV1 = theNbSV - 1;
// U step
Standard_Real dU = (u1 - u0) / Standard_Real(aNbSamplesU1);
// V step
Standard_Real dV = (v1 - v0) / Standard_Real(aNbSamplesV1);
// Fill arrays
for (Standard_Integer i = 0; i < theNbSU; ++i) {
Standard_Real aU = u0 + i*dU;
if (i == aNbSamplesU1) {
aU = u1;
}
theUPars.SetValue(i + 1, aU);
}
//
for (Standard_Integer i = 0; i < theNbSV; ++i) {
Standard_Real aV = v0 + i*dV;
if (i == aNbSamplesV1) {
aV = v1;
}
theVPars.SetValue(i + 1, aV);
}
}
//=======================================================================
//function : ComputeDeflection
//purpose :
//=======================================================================
Standard_Real IntPolyh_Tools::ComputeDeflection(const Handle(Adaptor3d_HSurface)& theSurf,
const TColStd_Array1OfReal& theUPars,
const TColStd_Array1OfReal& theVPars)
{
IntCurveSurface_ThePolyhedronOfHInter polyhedron(theSurf, theUPars, theVPars);
Standard_Real aDeflTol = polyhedron.DeflectionOverEstimation();
return aDeflTol;
}
//=======================================================================
//function : FillArrayOfPointNormal
//purpose :
//=======================================================================
void IntPolyh_Tools::FillArrayOfPointNormal(const Handle(Adaptor3d_HSurface)& theSurf,
const TColStd_Array1OfReal& theUPars,
const TColStd_Array1OfReal& theVPars,
IntPolyh_ArrayOfPointNormal& thePoints)
{
Standard_Integer aNbU = theUPars.Length();
Standard_Integer aNbV = theVPars.Length();
Standard_Integer iCnt = 0;
thePoints.Init(aNbU * aNbV);
for (Standard_Integer i = 1; i <= aNbU; ++i)
{
Standard_Real aU = theUPars(i);
for (Standard_Integer j = 1; j <= aNbV; ++j)
{
Standard_Real aV = theVPars(j);
// Compute the point
gp_Pnt aP;
gp_Vec aDU, aDV;
theSurf->D1(aU, aV, aP, aDU, aDV);
// Compute normal
gp_Vec aVNorm = aDU.Crossed(aDV);
Standard_Real aLength = aVNorm.Magnitude();
if (aLength > gp::Resolution())
{
aVNorm /= aLength;
}
else
{
aVNorm.SetCoord(0.0, 0.0, 0.0);
}
// Save the pair
IntPolyh_PointNormal& aPN = thePoints[iCnt];
aPN.Point = aP;
aPN.Normal = aVNorm;
++iCnt;
}
}
thePoints.SetNbItems(iCnt);
}

View File

@ -0,0 +1,60 @@
// Created by: Eugeny MALTCHIKOV
// Copyright (c) 2017 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 _IntPolyh_Tools_HeaderFile
#define _IntPolyh_Tools_HeaderFile
#include <TColStd_Array1OfReal.hxx>
#include <IntPolyh_ArrayOfPointNormal.hxx>
class Adaptor3d_HSurface;
//! The class provides tools for surface sampling.
class IntPolyh_Tools
{
public:
//! Checks if the surface can be enlarged in U or V direction.
Standard_EXPORT static void IsEnlargePossible(const Handle(Adaptor3d_HSurface)& theSurf,
Standard_Boolean& theUEnlarge,
Standard_Boolean& theVEnlarge);
//! Makes the sampling of the given surface <theSurf>
//! making the net of <theNbSU> x <theNbSV> sampling points.
//! The flag <theEnlargeZone> controls the enlargement of the
//! sampling zone on the surface.
//! The parameters of the sampling points are stored into
//! <theUPars> and <theVPars> arrays.
Standard_EXPORT static void MakeSampling(const Handle(Adaptor3d_HSurface)& theSurf,
const Standard_Integer theNbSU,
const Standard_Integer theNbSV,
const Standard_Boolean theEnlargeZone,
TColStd_Array1OfReal& theUPars,
TColStd_Array1OfReal& theVPars);
//! Computes the deflection tolerance on the surface for the given sampling.
Standard_EXPORT static Standard_Real ComputeDeflection(const Handle(Adaptor3d_HSurface)& theSurf,
const TColStd_Array1OfReal& theUPars,
const TColStd_Array1OfReal& theVPars);
//! Fills the array <thePoints> with the points (triangulation nodes) on the surface
//! and normal directions of the surface in these points.
Standard_EXPORT static void FillArrayOfPointNormal(const Handle(Adaptor3d_HSurface)& theSurf,
const TColStd_Array1OfReal& theUPars,
const TColStd_Array1OfReal& theVPars,
IntPolyh_ArrayOfPointNormal& thePoints);
};
#endif // _IntPolyh_Tools_HeaderFile

View File

@ -7,7 +7,6 @@ IntTools_BaseRangeSample.hxx
IntTools_BaseRangeSample.lxx
IntTools_BeanFaceIntersector.cxx
IntTools_BeanFaceIntersector.hxx
IntTools_BeanFaceIntersector.lxx
IntTools_CArray1.gxx
IntTools_CArray1.lxx
IntTools_CArray1OfInteger.hxx

View File

@ -125,7 +125,6 @@ myVMinParameter(0.),
myVMaxParameter(0.),
myBeanTolerance(0.),
myFaceTolerance(0.),
myDeflection(0.01),
myIsDone(Standard_False)
{
myCriteria = Precision::Confusion();
@ -147,7 +146,6 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const TopoDS_Edge& th
myVMaxParameter(0.),
myBeanTolerance(0.),
myFaceTolerance(0.),
myDeflection(0.01),
myIsDone(Standard_False)
{
Init(theEdge, theFace);
@ -167,7 +165,6 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Cur
myUMaxParameter(0.),
myVMinParameter(0.),
myVMaxParameter(0.),
myDeflection(0.01),
myIsDone(Standard_False)
{
Init(theCurve, theSurface, theBeanTolerance, theFaceTolerance);
@ -195,7 +192,6 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Cur
myVMaxParameter(theVMaxParameter),
myBeanTolerance(theBeanTolerance),
myFaceTolerance(theFaceTolerance),
myDeflection(0.01),
myIsDone(Standard_False)
{
myCurve = theCurve;
@ -322,142 +318,93 @@ void IntTools_BeanFaceIntersector::SetSurfaceParameters(const Standard_Real theU
// function: Perform
// purpose:
// ==================================================================================
void IntTools_BeanFaceIntersector::Perform()
void IntTools_BeanFaceIntersector::Perform()
{
myIsDone = Standard_False;
myResults.Clear();
Standard_Integer bRet;
Standard_Integer aDiscretization = 30;
Standard_Real aRelativeDeflection = 0.01;
myDeflection = aRelativeDeflection;
//
if (myContext.IsNull()) {
if (myContext.IsNull())
{
myContext=new IntTools_Context;
}
//
if(myCurve.GetType()==GeomAbs_Line && mySurface.GetType()==GeomAbs_Plane) {
// Fast computation of Line/Plane case
if (myCurve.GetType() == GeomAbs_Line &&
mySurface.GetType() == GeomAbs_Plane)
{
ComputeLinePlane();
return;
}
if(myCurve.GetType()==GeomAbs_Line) {
aDiscretization = 3;
myDeflection = Precision::Confusion();
}
else {
if(myCurve.GetType()==GeomAbs_Circle) {
aDiscretization = 23;
Standard_Real R = myCurve.Circle().Radius();
myDeflection = aRelativeDeflection * R;
}
if(myCurve.GetType() == GeomAbs_Ellipse) {
aDiscretization = 23;
Standard_Real R = myCurve.Ellipse().MajorRadius();
myDeflection = 2 * aRelativeDeflection * R;
}
}
// modified by NIZHNY-MKK Wed Oct 19 12:15:21 2005
Standard_Boolean bLocalize = Standard_False;
if(((mySurface.GetType() == GeomAbs_BSplineSurface) &&
((mySurface.UDegree() > 2) || (mySurface.VDegree() > 2)) &&
//modified by NIZNHY-PKV Wed Feb 25 15:02:00 2009f
//((mySurface.NbUKnots() > 2) || (mySurface.NbVKnots() > 2))) ||
((mySurface.NbUKnots() > 2) && (mySurface.NbVKnots() > 2))) ||
//modified by NIZNHY-PKV Wed Feb 25 15:02:13 2009t
(mySurface.GetType() == GeomAbs_BezierSurface) ||
(mySurface.GetType() == GeomAbs_OtherSurface)) {
bLocalize = Standard_True;
// Fast check on coincidence for analytic cases
if (FastComputeAnalytic())
{
// no further computation is necessary
myIsDone = Standard_True;
return;
}
if(bLocalize) {
if(Precision::IsInfinite(myUMinParameter) ||
Precision::IsInfinite(myUMaxParameter) ||
Precision::IsInfinite(myVMinParameter) ||
Precision::IsInfinite(myVMaxParameter))
bLocalize = Standard_False;
}
Standard_Boolean bSuccessLocalize = Standard_False;
// Initialization of the range manager
myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
if( bLocalize) {
myRangeManager.SetBoundaries(myFirstParameter, myLastParameter, 0);
Standard_Boolean coinside = TestComputeCoinside();
if(!coinside)
bSuccessLocalize = ComputeLocalized();
// Check coincidence
Standard_Boolean isCoincide = TestComputeCoinside();
if (isCoincide)
{
myResults.Append(IntTools_Range(myFirstParameter, myLastParameter));
myIsDone = Standard_True;
return;
}
if(!bLocalize || !bSuccessLocalize) {
// modified by NIZHNY-MKK Wed Oct 19 12:15:26 2005.END
// Perform intersection
IntTools_CArray1OfReal aParams;
if(IntTools::PrepareArgs(myCurve,
myLastParameter,
myFirstParameter,
aDiscretization,
aRelativeDeflection,
aParams)) {
return;
}
// try to find localized solution
Standard_Boolean bLocalize = (!Precision::IsInfinite(myUMinParameter) &&
!Precision::IsInfinite(myUMaxParameter) &&
!Precision::IsInfinite(myVMinParameter) &&
!Precision::IsInfinite(myVMaxParameter));
bLocalize = bLocalize && (mySurface.GetType() == GeomAbs_BezierSurface ||
mySurface.GetType() == GeomAbs_OtherSurface ||
(mySurface.GetType() == GeomAbs_BSplineSurface &&
(mySurface.UDegree() > 2 || mySurface.VDegree() > 2) &&
(mySurface.NbUKnots() > 2 && mySurface.NbVKnots() > 2)));
myRangeManager.SetRanges(aParams, 0);
Standard_Boolean isLocalized = bLocalize && ComputeLocalized();
if(myRangeManager.Length()==0) {
return;
}
//
bRet=FastComputeExactIntersection();
if(bRet == 1) {
IntTools_Range aRange(myFirstParameter, myLastParameter);
myResults.Append(aRange);
myIsDone = Standard_True;
return;
}
//modified by NIZHNY-EMV Fri Apr 20 09:38:08 2012
else if (bRet == 2) {
myIsDone = Standard_True;
return;
}
//modified by NIZHNY-EMV Fri Apr 20 09:38:10 2012
// Perform real intersection
if (!isLocalized)
{
ComputeAroundExactIntersection();
ComputeUsingExtremum();
// Standard_Boolean coinside = TestCoinside(myCurve,mySurface);
Standard_Boolean coinside = TestComputeCoinside();
// if(coinside) {
// myRangeManager.InsertRange(myFirstParameter, myLastParameter, 2);
// }
// else {
if(!coinside) {
ComputeAroundExactIntersection();
ComputeUsingExtremum();
ComputeNearRangeBoundaries();
}
ComputeNearRangeBoundaries();
}
myIsDone = Standard_True;
for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
// Treatment of the results
for (Standard_Integer i = 1; i <= myRangeManager.Length(); i++)
{
if (myRangeManager.Flag(i) != 2)
continue;
if(myRangeManager.Flag(i) == 2) {
IntTools_Range aRange = myRangeManager.Range(i);
if(myResults.Length() > 0) {
const IntTools_Range& aLastRange = myResults.Last();
if(Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion()) {
myResults.Append(aRange);
}
else {
myResults.ChangeValue(myResults.Length()).SetLast(aRange.Last());
}
}
else {
IntTools_Range aRange = myRangeManager.Range(i);
Standard_Integer iLastRange = myResults.Length();
if (iLastRange > 0)
{
IntTools_Range& aLastRange = myResults.ChangeValue(iLastRange);
if (Abs(aRange.First() - aLastRange.Last()) > Precision::PConfusion())
{
myResults.Append(aRange);
}
else
{
aLastRange.SetLast(aRange.Last());
}
}
else
myResults.Append(aRange);
}
}
@ -721,238 +668,127 @@ void IntTools_BeanFaceIntersector::ComputeAroundExactIntersection()
// function: FastComputeExactIntersection
// purpose:
// ==================================================================================
Standard_Integer IntTools_BeanFaceIntersector::FastComputeExactIntersection()
Standard_Boolean IntTools_BeanFaceIntersector::FastComputeAnalytic()
{
Standard_Integer aresult;
GeomAbs_CurveType aCT;
GeomAbs_SurfaceType aST;
//
aresult = 0;
aCT=myCurve.GetType();
aST=mySurface.GetType();
//
if((aCT==GeomAbs_BezierCurve) ||
(aCT==GeomAbs_BSplineCurve) ||
(aCT==GeomAbs_OffsetCurve) ||
(aCT==GeomAbs_OtherCurve)) {
return aresult;
GeomAbs_CurveType aCT = myCurve.GetType();
if (aCT == GeomAbs_BezierCurve ||
aCT == GeomAbs_BSplineCurve ||
aCT == GeomAbs_OffsetCurve ||
aCT == GeomAbs_OtherCurve)
{
// not supported type
return Standard_False;
}
if(aST==GeomAbs_Plane) {
Standard_Boolean isCoincide = Standard_False;
Standard_Boolean hasIntersection = Standard_True;
GeomAbs_SurfaceType aST = mySurface.GetType();
// Plane - Circle/Ellipse/Hyperbola/Parabola
if (aST == GeomAbs_Plane)
{
gp_Pln surfPlane = mySurface.Plane();
if(aCT==GeomAbs_Line) {
if((surfPlane.Distance(myCurve.Value(myFirstParameter)) < myCriteria) &&
(surfPlane.Distance(myCurve.Value(myLastParameter)) < myCriteria)) {
aresult = 1;
gp_Dir aDir;
gp_Pnt aPLoc;
switch (aCT) {
case GeomAbs_Circle:
{
aDir = myCurve.Circle().Axis().Direction();
aPLoc = myCurve.Circle().Location();
break;
}
case GeomAbs_Ellipse:
{
aDir = myCurve.Ellipse().Axis().Direction();
aPLoc = myCurve.Ellipse().Location();
break;
}
case GeomAbs_Hyperbola:
{
aDir = myCurve.Hyperbola().Axis().Direction();
aPLoc = myCurve.Hyperbola().Location();
break;
}
case GeomAbs_Parabola:
{
aDir = myCurve.Parabola().Axis().Direction();
aPLoc = myCurve.Parabola().Location();
break;
}
default:
return Standard_False;
}
else { // else 1
gp_Dir aDir;
switch(aCT) {
case GeomAbs_Circle: {
aDir = myCurve.Circle().Axis().Direction();
break;
}
case GeomAbs_Ellipse: {
aDir = myCurve.Ellipse().Axis().Direction();
break;
}
case GeomAbs_Hyperbola: {
aDir = myCurve.Hyperbola().Axis().Direction();
break;
}
case GeomAbs_Parabola: {
aDir = myCurve.Parabola().Axis().Direction();
break;
}
default: {
return aresult;
}
}
//
Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
if(anAngle < Precision::Angular()) {
Standard_Boolean insertRange = Standard_False;
switch(aCT) {
case GeomAbs_Circle: {
Standard_Real adist =
surfPlane.Distance(myCurve.Circle().Location()) +
myCurve.Circle().Radius() * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
case GeomAbs_Ellipse: {
Standard_Real adist =
surfPlane.Distance(myCurve.Ellipse().Location()) +
myCurve.Ellipse().MajorRadius() * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
case GeomAbs_Hyperbola:
case GeomAbs_Parabola: {
Standard_Real aMaxPar =
(Abs(myFirstParameter) > Abs(myLastParameter)) ?
Abs(myFirstParameter) : Abs(myLastParameter);
gp_Pnt aLoc = (aCT == GeomAbs_Parabola) ?
myCurve.Parabola().Location() :
myCurve.Hyperbola().Location();
Standard_Real adist = aLoc.Distance(myCurve.Value(aMaxPar));
adist = surfPlane.Distance(aLoc) + adist * Precision::Angular();
if(adist < myCriteria) {
insertRange = Standard_True;
}
break;
}
default: {
break;
}
}
//
if(insertRange) {
aresult = 1;
}
}//if(anAngle < Precision::Angular()) {
}//else { // else 1
}// if(aST==GeomAbs_Plane) {
if(aCT==GeomAbs_Circle) {
gp_Circ aCircle = myCurve.Circle();
Standard_Real anAngle = aDir.Angle(surfPlane.Axis().Direction());
if (anAngle > Precision::Angular())
return Standard_False;
if(aST==GeomAbs_Cylinder) {
gp_Cylinder aCylinder = mySurface.Cylinder();
gp_Dir aDir1(aCylinder.Axis().Direction());
gp_Dir aDir2(aCircle.Axis().Direction());
Standard_Real anAngle = aDir1.Angle(aDir2);
if(anAngle < Precision::Angular()) {
gp_Pnt aLoc = aCircle.Location();
gp_Lin anCylAxis(aCylinder.Axis());
Standard_Real alocdist = anCylAxis.Distance(aLoc);
Standard_Real adist = alocdist;
Standard_Real adiff = aCircle.Radius() - aCylinder.Radius();
adist += Abs(adiff);
if(adist < myCriteria) {
Standard_Real acylradius = aCylinder.Radius();
Standard_Real atmpvalue = aCircle.Radius() * sin(Precision::Angular());
Standard_Real aprojectedradius = atmpvalue;
aprojectedradius =
sqrt((aCircle.Radius() * aCircle.Radius())
- (aprojectedradius * aprojectedradius));
adiff = aprojectedradius - acylradius;
adist = alocdist + Abs(adiff);
if(adist < myCriteria) { // Abs is important function here
aresult = 1;
}
}
}
}// if(aST==GeomAbs_Cylinder)
hasIntersection = Standard_False;
if(aST==GeomAbs_Sphere) {
gp_Pln aCirclePln(aCircle.Location(), aCircle.Axis().Direction());
IntAna_QuadQuadGeo anInter(aCirclePln, mySurface.Sphere());
if(anInter.IsDone()) {
if(anInter.TypeInter() == IntAna_Circle) {
gp_Circ aCircleToCompare = anInter.Circle(1);
Standard_Real adist =
aCircleToCompare.Location().Distance(aCircle.Location());
Standard_Real adiff = aCircle.Radius() - aCircleToCompare.Radius();
adist += Abs(adiff);
if(adist < myCriteria) {
aresult = 1;
}
}
}
}// if(aST==GeomAbs_Sphere) {
}// if(aCT==GeomAbs_Circle) {
//
//modified by NIZNHY-PKV Thu Mar 01 11:54:04 2012f
if(aST==GeomAbs_Cylinder) {
Standard_Real aRC;
gp_Cylinder aCyl;
//
aCyl=mySurface.Cylinder();
aRC=aCyl.Radius();
const gp_Ax1& aAx1C=aCyl.Axis();
const gp_Dir& aDirC=aAx1C.Direction();
//
if(aCT==GeomAbs_Line) {
Standard_Real aCos, aAng2, aTolang2;
gp_Lin aLin;
//
aTolang2=1.e-16;
aLin=myCurve.Line();
const gp_Dir& aDirL=aLin.Direction();
//
aCos=aDirC.Dot(aDirL);
if(aCos >= 0.) {
aAng2 = 2.*(1. - aCos);
}
else {
aAng2 = 2.*(1. + aCos);
}
//
if(aAng2<=aTolang2) {// IsParallel = Standard_True;
Standard_Boolean bFlag = Standard_False;
Standard_Integer i;
Standard_Real aD;
gp_Pnt aPL[2];
gp_Lin aLC(aAx1C);
//
aPL[0]=myCurve.Value(myFirstParameter);
aPL[1]=myCurve.Value(myLastParameter);
//
for (i=0; i<2; ++i) {
aD=aLC.Distance(aPL[i]);
aD=fabs(aD-aRC);
bFlag=(aD > myCriteria);
if (bFlag) {
break;
}
}
if (!bFlag){
aresult = 1;
}
}
}//if(aCT==GeomAbs_Line) {
Standard_Real aDist = surfPlane.Distance(aPLoc);
isCoincide = aDist < myCriteria;
}
//modified by NIZNHY-PKV Thu Mar 01 11:54:06 2012t
//
if (aresult==1) {
//check intermediate point
Standard_Real aTm;
Standard_Boolean bValid;
//
const TopoDS_Face& aF = mySurface.Face();
aTm = IntTools_Tools::IntermediatePoint(myFirstParameter, myLastParameter);
const gp_Pnt& aPm = myCurve.Value(aTm);
//
bValid = myContext->IsValidPointForFace(aPm, aF, myCriteria);
if (bValid) {
IntTools_Range aRange(myFirstParameter, myLastParameter);
myRangeManager.InsertRange(aRange, 2);
} else {
aresult=2;
// Cylinder - Line/Circle
else if (aST == GeomAbs_Cylinder)
{
gp_Cylinder aCylinder = mySurface.Cylinder();
const gp_Ax1& aCylAxis = aCylinder.Axis();
const gp_Dir& aCylDir = aCylAxis.Direction();
Standard_Real aCylRadius = aCylinder.Radius();
if (aCT == GeomAbs_Line)
{
gp_Lin aLin = myCurve.Line();
if (!aLin.Direction().IsParallel(aCylDir, Precision::Angular()))
return Standard_False;
hasIntersection = Standard_False;
Standard_Real aDist = Abs(aLin.Distance(aCylAxis.Location()) - aCylRadius);
isCoincide = (aDist < myCriteria);
}
else if (aCT == GeomAbs_Circle)
{
gp_Circ aCircle = myCurve.Circle();
Standard_Real anAngle = aCylDir.Angle(aCircle.Axis().Direction());
if (anAngle > Precision::Angular())
return Standard_False;
Standard_Real aDistLoc = gp_Lin(aCylAxis).Distance(aCircle.Location());
Standard_Real aDist = aDistLoc + Abs(aCircle.Radius() - aCylRadius);
isCoincide = (aDist < myCriteria);
if (!isCoincide)
hasIntersection = (aDistLoc - (aCircle.Radius() + aCylRadius)) < myCriteria &&
(Abs(aCircle.Radius() - aCylRadius) - aDistLoc) < myCriteria;
}
}
//
return aresult;
// Sphere - Line
else if (aST == GeomAbs_Sphere)
{
gp_Sphere aSph = mySurface.Sphere();
gp_Pnt aSphLoc = aSph.Location();
if (aCT == GeomAbs_Line)
{
gp_Lin aLin = myCurve.Line();
Standard_Real aDist = aLin.Distance(aSphLoc) - aSph.Radius();
hasIntersection = aDist < myCriteria;
}
}
// Check intermediate point
if (isCoincide)
{
myResults.Append(IntTools_Range(myFirstParameter, myLastParameter));
}
return isCoincide || !hasIntersection;
}
// ==================================================================================
@ -1057,10 +893,6 @@ void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
myUMaxParameter,
myVMinParameter,
myVMaxParameter);
Bnd_Box FBox;
BndLib_AddSurface::Add(mySurface, 0., FBox);
FBox.Enlarge(myFaceTolerance);
for(Standard_Integer i = 1; i <= myRangeManager.Length(); i++) {
@ -1073,24 +905,13 @@ void IntTools_BeanFaceIntersector::ComputeUsingExtremum()
if(anarg2 - anarg1 < Precision::PConfusion()) {
if(((i > 1) && (myRangeManager.Flag(i-1) == 2)) ||
((i < myRangeManager.Length()) && (myRangeManager.Flag(i+1) == 2))) {
myRangeManager.SetFlag(i, 1);
continue;
if (((i > 1) && (myRangeManager.Flag(i - 1) == 2)) ||
((i < myRangeManager.Length()) && (myRangeManager.Flag(i + 1) == 2))) {
myRangeManager.SetFlag(i, 1);
continue;
}
}
// check bounding boxes
Bnd_Box EBox;
EBox.Add(myCurve.Value(anarg1));
EBox.Add(myCurve.Value(anarg2));
EBox.Enlarge(myBeanTolerance + myDeflection);
if(EBox.IsOut(FBox)) {
myRangeManager.SetFlag(i, 1);
continue;
}
GeomAdaptor_Curve aGACurve(aCurve, anarg1, anarg2);
Extrema_ExtCS theExtCS(aGACurve, aGASurface, Tol, Tol);
myExtrema = theExtCS;

View File

@ -120,7 +120,11 @@ public:
//! Launches the algorithm
Standard_EXPORT void Perform();
Standard_Boolean IsDone() const;
//! Returns Done/NotDone state of the algorithm.
Standard_Boolean IsDone() const
{
return myIsDone;
}
Standard_EXPORT const IntTools_SequenceOfRanges& Result() const;
@ -142,7 +146,12 @@ private:
Standard_EXPORT void ComputeLinePlane();
Standard_EXPORT Standard_Integer FastComputeExactIntersection();
//! Fast check on coincidence of the edge with face for the cases when both shapes are
//! based on analytic geometries. The method also computes if the intersection
//! between shapes is possible.
//! The method returns TRUE if the computation was successful and further computation is unnecessary.
//! Otherwise it returns FALSE and computation continues.
Standard_EXPORT Standard_Boolean FastComputeAnalytic();
Standard_EXPORT void ComputeUsingExtremum();
@ -179,19 +188,10 @@ private:
Extrema_ExtCS myExtrema;
GeomAPI_ProjectPointOnSurf myProjector;
IntTools_MarkedRangeSet myRangeManager;
Standard_Real myDeflection;
Handle(IntTools_Context) myContext;
IntTools_SequenceOfRanges myResults;
Standard_Boolean myIsDone;
};
#include <IntTools_BeanFaceIntersector.lxx>
#endif // _IntTools_BeanFaceIntersector_HeaderFile

View File

@ -68,146 +68,11 @@ static
IntTools_EdgeFace::IntTools_EdgeFace()
{
myFuzzyValue = Precision::Confusion();
myDiscret = 30;
myEpsT =1e-12;
myDeflection=0.01;
myIsDone=Standard_False;
myErrorStatus=1;
myQuickCoincidenceCheck=Standard_False;
}
//=======================================================================
//function : SetContext
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetContext(const Handle(IntTools_Context)& theContext)
{
myContext = theContext;
}
//=======================================================================
//function : Context
//purpose :
//=======================================================================
const Handle(IntTools_Context)& IntTools_EdgeFace::Context()const
{
return myContext;
}
//=======================================================================
//function : SetEdge
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetEdge(const TopoDS_Edge& anEdge)
{
myEdge=anEdge;
}
//=======================================================================
//function : SetFace
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
{
myFace=aFace;
}
//=======================================================================
//function : Edge
//purpose :
//=======================================================================
const TopoDS_Edge& IntTools_EdgeFace::Edge()const
{
return myEdge;
}
//=======================================================================
//function : Face
//purpose :
//=======================================================================
const TopoDS_Face& IntTools_EdgeFace::Face()const
{
return myFace;
}
//=======================================================================
//function : SetFuzzyValue
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetFuzzyValue(const Standard_Real theFuzz)
{
myFuzzyValue = Max(theFuzz, Precision::Confusion());
}
//=======================================================================
//function : SetDiscretize
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetDiscretize(const Standard_Integer aDiscret)
{
myDiscret=aDiscret;
}
//=======================================================================
//function : SetDeflection
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetDeflection(const Standard_Real aDefl)
{
myDeflection=aDefl;
}
//=======================================================================
//function : SetEpsilonT
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetEpsilonT(const Standard_Real anEpsT)
{
myEpsT=anEpsT;
}
//=======================================================================
//function : SetRange
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetRange(const Standard_Real aFirst,
const Standard_Real aLast)
{
myRange.SetFirst (aFirst);
myRange.SetLast (aLast);
}
//=======================================================================
//function : SetRange
//purpose :
//=======================================================================
void IntTools_EdgeFace::SetRange(const IntTools_Range& aRange)
{
SetRange(aRange.First(), aRange.Last());
}
//=======================================================================
//function : IsDone
//purpose :
//=======================================================================
Standard_Boolean IntTools_EdgeFace::IsDone()const
{
return myIsDone;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
Standard_Integer IntTools_EdgeFace::ErrorStatus()const
{
return myErrorStatus;
}
//=======================================================================
//function : CommonParts
//purpose :
//=======================================================================
const IntTools_SequenceOfCommonPrts& IntTools_EdgeFace::CommonParts() const
{
return mySeqOfCommonPrts;
}
//=======================================================================
//function : Range
//purpose :
//=======================================================================
const IntTools_Range& IntTools_EdgeFace::Range() const
{
return myRange;
}
//=======================================================================
//function : IsCoincident
//purpose :
//=======================================================================
@ -352,7 +217,7 @@ Standard_Real IntTools_EdgeFace::DistanceFunction
//
if (!bFlag) {
myErrorStatus=11;
myErrorStatus = 4;
return 99.;
}
@ -597,11 +462,11 @@ Standard_Boolean IntTools_EdgeFace::CheckTouch
return theflag;
}
if (fabs (aTx-aTF) < myEpsT) {
if (fabs (aTx-aTF) < Precision::PConfusion()) {
return !theflag;
}
if (fabs (aTx-aTL) < myEpsT) {
if (fabs (aTx-aTL) < Precision::PConfusion()) {
return !theflag;
}
@ -769,16 +634,6 @@ void IntTools_EdgeFace::Perform()
myIsDone=Standard_True;
}
//
// myErrorStatus
// 1 - the method Perform() is not invoked
// 2,3,4,5 -the method CheckData() fails
// 6 - PrepareArgs() problems
// 7 - No Projectable ranges
// 8,9 - PrepareArgs() problems occured inside projectable Ranges
// 11 - can't fill array aFunc(i) in PrepareArgsFuncArrays
//=======================================================================
//function : CheckTouch
//purpose :

View File

@ -38,113 +38,148 @@ class gp_Pnt;
class BRepAdaptor_Surface;
class IntTools_CommonPrt;
//! The class provides Edge/Face algorithm to determine
//! common parts between edge and face in 3-d space.
//! Common parts can be : Vertices or Edges.
//! The class provides Edge/Face intersection algorithm to determine
//! common parts between edge and face in 3-d space.
//! Common parts between Edge and Face can be:
//! - Vertices - in case of intersection or touching;
//! - Edge - in case of full coincidence of the edge with the face.
class IntTools_EdgeFace
{
public:
DEFINE_STANDARD_ALLOC
public: //! @name Constructors
//! Empty Constructor
Standard_EXPORT IntTools_EdgeFace();
//! Initializes algorithm by the edge anEdge
Standard_EXPORT void SetEdge (const TopoDS_Edge& anEdge);
public: //! @name Setters/Getters
//! Initializes algorithm by the face aFace
Standard_EXPORT void SetFace (const TopoDS_Face& aFace);
//! Sets the edge for intersection
void SetEdge(const TopoDS_Edge& theEdge)
{
myEdge = theEdge;
}
//! Returns edge
Standard_EXPORT const TopoDS_Edge& Edge() const;
//! Returns the edge
const TopoDS_Edge& Edge() const
{
return myEdge;
}
//! Returns face
Standard_EXPORT const TopoDS_Face& Face() const;
//! Sets the face for intersection
void SetFace(const TopoDS_Face& theFace)
{
myFace = theFace;
}
//! Initializes algorithm by discretization value
Standard_EXPORT void SetDiscretize (const Standard_Integer aDiscret);
//! Returns the face
const TopoDS_Face& Face() const
{
return myFace;
}
//! Initializes algorithm by deflection value
Standard_EXPORT void SetDeflection (const Standard_Real aDeflection);
//! Initializes algorithm by parameter tolerance
Standard_EXPORT void SetEpsilonT (const Standard_Real anEpsT);
//! Sets boundaries for edge.
//! Sets the boundaries for the edge.
//! The algorithm processes edge inside these boundaries.
Standard_EXPORT void SetRange (const IntTools_Range& aRange);
void SetRange(const IntTools_Range& theRange)
{
myRange = theRange;
}
//! Sets boundaries for edge.
//! Sets the boundaries for the edge.
//! The algorithm processes edge inside these boundaries.
Standard_EXPORT void SetRange (const Standard_Real aFirst, const Standard_Real aLast);
void SetRange(const Standard_Real theFirst, const Standard_Real theLast)
{
myRange.SetFirst(theFirst);
myRange.SetLast(theLast);
}
//! Sets the intersecton context
Standard_EXPORT void SetContext (const Handle(IntTools_Context)& theContext);
//! Returns intersection range of the edge
const IntTools_Range& Range() const
{
return myRange;
}
//! Sets the intersection context
void SetContext(const Handle(IntTools_Context)& theContext)
{
myContext = theContext;
}
//! Returns the intersection context
const Handle(IntTools_Context)& Context() const
{
return myContext;
}
//! Gets the intersecton context
Standard_EXPORT const Handle(IntTools_Context)& Context() const;
//! Sets the Fuzzy value
Standard_EXPORT void SetFuzzyValue(const Standard_Real theFuzz);
void SetFuzzyValue(const Standard_Real theFuzz)
{
myFuzzyValue = Max(theFuzz, Precision::Confusion());
}
//! Returns Fuzzy value
//! Returns the Fuzzy value
Standard_Real FuzzyValue() const
{
return myFuzzyValue;
}
//! Launches the process
Standard_EXPORT void Perform();
//! Returns true if computation was done
//! successfully, otherwise returns false
Standard_EXPORT Standard_Boolean IsDone() const;
//! Returns code of completion
//! 0 - means successful completion
//! 1 - the process was not started
//! 2,3,4,5 - invalid source data for the algorithm
//! 6 - discretization failed
//! 7 - no projectable ranges found
//! 11 - distance computing error
Standard_EXPORT Standard_Integer ErrorStatus() const;
//! Returns results
Standard_EXPORT const IntTools_SequenceOfCommonPrts& CommonParts() const;
//! Returns boundaries for edge
Standard_EXPORT const IntTools_Range& Range() const;
//! Sets the flag myQuickCoincidenceCheck
void UseQuickCoincidenceCheck(const Standard_Boolean bFlag) {
myQuickCoincidenceCheck=bFlag;
//! Sets the flag for quick coincidence check.
//! It is safe to use the quick check for coincidence only if both
//! of the following conditions are met:
//! - The vertices of edge are lying on the face;
//! - The edge does not intersect the boundaries of the face on the given range.
void UseQuickCoincidenceCheck(const Standard_Boolean theFlag)
{
myQuickCoincidenceCheck = theFlag;
}
//! Returns the flag myQuickCoincidenceCheck
Standard_Boolean IsCoincidenceCheckedQuickly () {
Standard_Boolean IsCoincidenceCheckedQuickly()
{
return myQuickCoincidenceCheck;
}
protected:
public: //! @name Performing the operation
//! Launches the process
Standard_EXPORT void Perform();
public: //! @name Checking validity of the intersection
//! Returns TRUE if computation was successful.
//! Otherwise returns FALSE.
Standard_Boolean IsDone() const
{
return myIsDone;
}
//! Returns the code of completion:
//! 0 - means successful completion;
//! 1 - the process was not started;
//! 2,3 - invalid source data for the algorithm;
//! 4 - projection failed.
Standard_Integer ErrorStatus() const
{
return myErrorStatus;
}
public: //! @name Obtaining results
//! Returns resulting common parts
const IntTools_SequenceOfCommonPrts& CommonParts() const
{
return mySeqOfCommonPrts;
}
protected: //! @name Protected methods performing the intersection
Standard_EXPORT static Standard_Boolean IsEqDistance (const gp_Pnt& aP, const BRepAdaptor_Surface& aS, const Standard_Real aT, Standard_Real& aD);
Standard_EXPORT void CheckData();
@ -161,18 +196,11 @@ protected:
//! Checks if the edge is in the face really.
Standard_EXPORT Standard_Boolean IsCoincident();
private:
TopoDS_Edge myEdge;
TopoDS_Face myFace;
Standard_Real myFuzzyValue;
Standard_Integer myDiscret;
Standard_Real myEpsT;
Standard_Real myDeflection;
BRepAdaptor_Curve myC;
BRepAdaptor_Surface myS;
Standard_Real myCriteria;
@ -181,20 +209,7 @@ private:
Handle(IntTools_Context) myContext;
IntTools_SequenceOfCommonPrts mySeqOfCommonPrts;
IntTools_Range myRange;
//! Allows avoiding use Edge-Face intersection
//! algorithm (i.e. speeding up the Boolean algorithm)
//! if the edges are coincided really.
//! If it is not evidently set of this flag should
//! be avoided (otherwise, the performance of
//! Boolean algorithm will be slower).
Standard_Boolean myQuickCoincidenceCheck;
};
#endif // _IntTools_EdgeFace_HeaderFile

View File

@ -1,5 +1,4 @@
puts "TODO OCC27024 ALL: Error : operation bfuse is WRONG because number of SOLID entities in shape"
puts "TODO OCC27024 ALL: Faulty shapes in variables faulty_1 to faulty_"
puts "=========="
puts "BUC60462"
@ -13,8 +12,7 @@ puts "Fuse begin"
bfuse result a b
puts "Fuse end"
checkshape result r
checkshape result
checknbshapes result -solid 1 -m "operation bfuse"
checkprops result -s 93237.9
checkshape result
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -1,6 +1,3 @@
puts "TODO OCC12345 ALL: Error : The length of result shape is"
puts "TODO OCC12345 ALL: Faulty : Section is incorrect"
puts "============="
puts "BUC60463"
puts "============="
@ -18,8 +15,7 @@ if { $cs != 0 } {
puts "Faulty : Section is incorrect"
}
checkprops result -l 0
checkprops result -l 520.961
checkshape result
checksection result
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -10,18 +10,18 @@ polyline l 0 -10 -10 0 10 -10 0 10 10 0 -10 10 0 -10 -10
mkplane pl l
mksurface surf pl
vinit
vdisplay pl
vertex v1 10 -5 0
vertex v2 10 5 0
edge e v1 v2
mkcurve curv e
vdisplay e
vfit
set bug_info [extrema surf curv]
if {$bug_info != "No solutions!\n"} {
if {$bug_info != "Infinite number of extremas, distance = 10\n"} {
puts "ERROR: OCC25063 is reproduced."
}
checkview -screenshot -3d -path ${imagedir}/${test_image}.png
smallview
don pl e
fit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@ -24,8 +24,8 @@ explode line V
set tol_abs 0.001
set tol_rel 0
distmini d p_1_1 line_1
distmini d p_1_1 line_2
checkreal "Projection, p1" [dval d_val] 0 $tol_abs $tol_rel
distmini d p_1_2 line_2
distmini d p_1_2 line_1
checkreal "Projection, p2" [dval d_val] 0 $tol_abs $tol_rel

View File

@ -1,5 +1,3 @@
puts "TODO OCC25385 ALL: is not equal to expected"
puts "============"
puts "OCC25385"
puts "============"
@ -22,3 +20,5 @@ regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance s] full MaxTol_s_2
set tol_abs_MaxTol 0.0001
set tol_rel_MaxTol 0.0001
checkreal "MaxTolerance " ${MaxTol_s_2} ${MaxTol_s_1} ${tol_abs_MaxTol} ${tol_rel_MaxTol}
checkprops r -l 36.2401

View File

@ -15,11 +15,8 @@ mksurface s f
extrema c s
if { [isdraw ext_1] } {
mkedge result ext_1
checkprops result -l 1.88322e-11
checksection result
set len [lindex [length ext_1] end]
checkreal "Extrema min distance" $len 1.88322e-11 1.e-7 1.e-7
} else {
puts "Error: invalid result"
}
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -18,11 +18,8 @@ trim ct c 1.1167213545471877e-008 0.033333343614041021
extrema ct st
if { [isdraw ext_1] } {
mkedge result ext_1
checkprops result -l 1.00005e-07
checksection result
set len [lindex [length ext_1] end]
checkreal "Extrema min distance" $len 1.00005e-07 1.e-7 1.e-7
} else {
puts "Error: invalid result"
}
checkview -display result -2d -path ${imagedir}/${test_image}.png

View File

@ -8,11 +8,11 @@ set filename bm1_pe_t4.stp
set ref_data {
DATA : Faulties = 0 ( 0 ) Warnings = 0 ( 0 ) Summary = 0 ( 0 )
TPSTAT : Faulties = 0 ( 2 ) Warnings = 14 ( 28 ) Summary = 14 ( 30 )
TPSTAT : Faulties = 0 ( 3 ) Warnings = 13 ( 30 ) Summary = 13 ( 33 )
CHECKSHAPE : Wires = 3 ( 2 ) Faces = 3 ( 3 ) Shells = 0 ( 0 ) Solids = 0 ( 0 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) Summary = 142 ( 143 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 53 ( 51 )
TOLERANCE : MaxTol = 1562.051497 ( 1562.051497 ) AvgTol = 273.5183373 ( 208.7393976 )
NBSHAPES : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) Summary = 140 ( 141 )
STATSHAPE : Solid = 0 ( 0 ) Shell = 12 ( 12 ) Face = 15 ( 15 ) FreeWire = 0 ( 0 ) FreeEdge = 0 ( 0 ) SharedEdge = 52 ( 50 )
TOLERANCE : MaxTol = 1562.051497 ( 1562.051497 ) AvgTol = 272.6255712 ( 211.9512858 )
LABELS : N0Labels = 1 ( 1 ) N1Labels = 0 ( 0 ) N2Labels = 0 ( 0 ) TotalLabels = 1 ( 1 ) NameLabels = 1 ( 1 ) ColorLabels = 0 ( 0 ) LayerLabels = 0 ( 0 )
PROPS : Centroid = 0 ( 0 ) Volume = 0 ( 0 ) Area = 0 ( 0 )
NCOLORS : NColors = 0 ( 0 )

View File

@ -0,0 +1,18 @@
puts "========"
puts "OCC29426"
puts "========"
puts ""
########################################
# Extrema algorithm fails to find minimal distance between Circle and Sphere
########################################
circle c 3.59679185933224e-016 11.6635040382361 -3.23970209548358 -3.67401855705945e-017 -0.943656647634893 0.330926172090505 -2.2723161366922e-016 0.330926172090505 0.943656647634893 1.30000000000039
sphere s 0 2.425 0 0 1 0 1 -0 0 9.876
set log [extrema c s]
if {![regexp "Point" $log]} {
set ext_dist [lindex [length ext_1] end]
checkreal "Circle/Sphere min distance" $ext_dist 0. 1.e-10 1.e-10
}

View File

@ -0,0 +1,17 @@
puts "========"
puts "OCC29426"
puts "========"
puts ""
########################################
# Extrema algorithm fails to find minimal distance between Circle and Sphere
########################################
circle c 3.53600008984273e-016 11.5073628633636 -3.18494573739955 -3.67401855705945e-017 -0.943656647634893 0.330926172090505 -2.2723161366922e-016 0.330926172090505 0.943656647634893 1.30000000000039
sphere s 0 2.425 0 0 1 0 1 -0 0 9.712
set log [extrema c s]
if {![regexp "Point" $log]} {
set ext_dist [lindex [length ext_1] end]
checkreal "Circle/Sphere min distance" $ext_dist 0. 1.e-10 1.e-10
}

View File

@ -0,0 +1,127 @@
puts "======================="
puts "Test for Circle/Sphere extrema algorithm"
puts "Intersection case (two intersection points should be found"
puts "======================="
puts ""
# Make sphere
set x0 0.
set y0 0.
set z0 0.
set sph_radius 10.
sphere s $x0 $y0 $z0 $sph_radius
# All circles will be to connect the two points - one inside the sphere, another - outside.
# Such circle will definitely intersect the initial sphere in two points.
# The points to make the circle will taken two spheres - with smaller and bigger radius.
# Set the number of iterations (number of pairs of spheres)
set nbpairs 2
# Set ratio to increase/decrease the radius if additional spheres
set ratio_radius 2.
# Number of sampling points on the spheres
set nbsamples 5
# Number of circles rotations
set nbsteps 5
set angle [expr 180. / $nbsteps]
# Iteration step
set iStep 1
for {set i 1} {$i <= $nbpairs} {incr i} {
# Define the radius for spheres
set s_in_radius [expr $sph_radius / ($i * $ratio_radius)]
set s_out_radius [expr $sph_radius * ($i * $ratio_radius)]
# Make the spheres
sphere s_in $x0 $y0 $z0 $s_in_radius
sphere s_out $x0 $y0 $z0 $s_out_radius
# Make the sampling of the spheres
# spheres are the same, so there is no difference from which one to take the parameters
bounds s_in umin umax vmin vmax
set du [dval (umax-umin)/$nbsteps]
set dv [dval (vmax-vmin)/$nbsteps]
for {set u1 1} {$u1 <= $nbsamples} {incr u1} {
for {set v1 1} {$v1 <= $nbsamples} {incr v1} {
# point on inner sphere
svalue s_in [dval umin+$u1*$du] [dval vmin+$v1*$dv] x1 y1 z1
for {set u2 1} {$u2 <= $nbsamples} {incr u2} {
for {set v2 1} {$v2 <= $nbsamples} {incr v2} {
# point on outer sphere
svalue s_out [dval umin+$u2*$du] [dval vmin+$v2*$dv] x2 y2 z2
# rotation direction
set dx [dval x2-x1]
set dy [dval y2-y1]
set dz [dval z2-z1]
# center of the circle
set xc [dval (x1+x2)/2.]
set yc [dval (y1+y2)/2.]
set zc [dval (z1+z2)/2.]
# compute radius for circle
set cir_radius [expr sqrt($dx*$dx + $dy*$dy + $dz*$dz) / 2.]
# make plane to get its XAxis
plane p $xc $yc $zc $dx $dy $dz
regexp {XAxis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump p] full dxx dxy dxz
circle c $xc $yc $zc $dxx $dxy $dxz $cir_radius
# make rotation
copy c c_rotated
for {set j 1} {$j <= $nbsteps} {incr j} {
rotate c_rotated $xc $yc $zc $dx $dy $dz $angle
set log [extrema c_rotated s]
# save each circle if necessary
# copy c_rotated c_$iStep
set isfound1 0
set isfound2 0
if {[regexp "ext_1" $log]} {
set ext_dist [lindex [length ext_1] end]
checkreal "Step $iStep, min distance 1" $ext_dist 0 1.e-7 1.e-7
set isfound1 1
}
if {[regexp "ext_2" $log]} {
set ext_dist [lindex [length ext_2] end]
checkreal "Step $iStep, min distance 2" $ext_dist 0 1.e-7 1.e-7
set isfound2 1
}
if {[regexp "Extrema 1 is point" $log]} {
puts "Check of Step $iStep, min distance 1 OK"
set isfound1 1
}
if {[regexp "Extrema 2 is point" $log]} {
puts "Check of Step $iStep, min distance 2 OK"
set isfound2 1
}
if {$isfound1 == 0 || $isfound2 == 0} {
puts "Error: Extrema has not detected the intersection case on step $iStep"
}
incr iStep
}
}
}
}
}
}

View File

@ -0,0 +1,160 @@
puts "======================="
puts "Test for Circle/Sphere extrema algorithm"
puts "No intersection cases - one minimum solution should be found"
puts "======================="
puts ""
# Make sphere
set x0 0.
set y0 0.
set z0 0.
set sph_radius 10.
sphere s $x0 $y0 $z0 $sph_radius
# The circles will be made on the distance from the surface
# as intersection of pairs of inner and outer spheres with the plane
# Set the number of iterations
set nbstep 5
# Rotation angle
set angle [expr 180. / $nbstep]
# Set the number of Inner/Outer spheres in one direction
set nbpairs 1
# Set the delta for the radius of inner circle
set delta_radius [expr $sph_radius * 0.9 / (2 * $nbpairs)]
# Step for sampling of the circle
set dt [expr [dval 2*pi] / $nbstep]
# Iteration step
set iStep 1
for {set i 1} {$i <= $nbpairs} {incr i} {
# Define the inner circle
set circ_radius [expr $i * $delta_radius]
circle c $x0 $y0 $z0 0 0 1 $circ_radius
set diff [expr $sph_radius - $circ_radius]
# Distance between inner sphere on circle and initial sphere
set real_dist [expr $sph_radius - 2*$circ_radius]
# Circle will be rotated around the line
line rotation_line $x0 $y0 $z0 1 0 0
# Line rotation
for {set j 1} {$j <= $nbstep} {incr j} {
rotate rotation_line $x0 $y0 $z0 0 0 1 $angle
# Get direction for circle's rotation
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump rotation_line] full dx dy dz
# Circle rotation
copy c c_rotated
for {set k 1} {$k <= $nbstep} {incr k} {
rotate c_rotated 0 0 0 $dx $dy $dz $angle
# Sampling of the circle
for {set n 1} {$n <= $nbstep} {incr n} {
cvalue c_rotated $n*$dt x1 y1 z1
set x1 [dval x1]
set y1 [dval y1]
set z1 [dval z1]
# Normalize the vector
set dtx [expr ($x1 - $x0) / $circ_radius]
set dty [expr ($y1 - $y0) / $circ_radius]
set dtz [expr ($z1 - $z0) / $circ_radius]
# Create inner and outer spheres
set iC 1
repeat 2 {
sphere s_to_int $x1 $y1 $z1 $circ_radius
# Define the point closest to the initial sphere
set x_sol [expr $x1 + $iC * $circ_radius * $dtx]
set y_sol [expr $y1 + $iC * $circ_radius * $dty]
set z_sol [expr $z1 + $iC * $circ_radius * $dtz]
# Intersect the sphere with the plane originated in closes point
# Make the sampling of the sphere to define section plane's direction
bounds s_to_int umin umax vmin vmax
set du [dval (umax-umin)/$nbstep]
set dv [dval (vmax-vmin)/$nbstep]
for {set u 1} {$u <= $nbstep} {incr u} {
for {set v 1} {$v <= $nbstep} {incr v} {
# Get point on surface
svalue s_to_int [dval umin+$u*$du] [dval vmin+$v*$dv] xs ys zs
# Check that it is not the same point
set sqdist [dval (xs-$x_sol)*(xs-$x_sol)+(ys-$y_sol)*(ys-$y_sol)+(zs-$z_sol)*(zs-$z_sol)]
if {$sqdist < 1.e-16} {
# Skip the sampling point
continue;
}
# Create the intersection plane
plane p_int $x_sol $y_sol $z_sol [dval xs-$x_sol] [dval ys-$y_sol] [dval zs-$z_sol]
# Intersect the sphere by plane to obtain the circle
foreach c_int [intersect c_inter s_to_int p_int] {
# Check if the circle contains the point
if {![regexp "Point on curve" [proj $c_int $x_sol $y_sol $z_sol]]} {
if {[lindex [length ext_1] end] >= 1.e-7} {
# run extrema - one of the ends of the curve should be the solution
set log [extrema $c_int s 1]
if {[regexp "prm_1_1" $log]} {
# get parameters of the curve
bounds $c_int fp lp
if {[dval prm_1_1-fp] > 1.e-7 && [dval lp-prm_1_1] > 1.e-7} {
puts "Error: Extrema has failed to find the minimal distance on step $iStep"
}
} else {
puts "Error: Extrema has failed to find the minimal distance on step $iStep"
}
# save each circle if necessary
# copy $c_int c_$iStep
incr iStep
continue
}
}
# Make extrema computation
set log [extrema $c_int s]
# save each circle if necessary
# copy $c_int c_$iStep
if {![regexp "ext_1" $log]} {
puts "Error: Extrema has failed to find the minimal distance on step $iStep"
} else {
set ext_dist [lindex [length ext_1] end]
checkreal "Step $iStep, min distance " $ext_dist $real_dist 1.e-7 1.e-7
}
incr iStep
}
}
}
# prepare for the outer sphere
set x1 [expr $x1 + 2 * $diff * $dtx]
set y1 [expr $y1 + 2 * $diff * $dty]
set z1 [expr $z1 + 2 * $diff * $dtz]
set iC -1
}
}
}
}
}

View File

@ -0,0 +1,82 @@
puts "======================="
puts "Test for Circle/Sphere extrema algorithm"
puts "Parallel case (center of sphere is on the circle's axis)"
puts "======================="
puts ""
# Make sphere
set x0 0.
set y0 0.
set z0 0.
set sph_radius 10.
sphere s $x0 $y0 $z0 $sph_radius
# Initially the circle will be made at the same place as sphere with different radius
# and will be rotated and shifted many times.
# The distance between circle and sphere is a Abs(sqrt(centers_dist^2 + circ_radius^2) - sph_radius)
# Number of different radius of initial circle
set nb_radius 7
# Number of circle's rotations
set nbstep 8
set angle [expr 180. / $nbstep]
# Define the shift
set shift_start -3
set shift_end 3
set shift 4
# Iteration step
set iStep 1
for {set i 1} {$i < $nb_radius} {incr i} {
set circ_radius [expr $i*2.]
circle c $x0 $y0 $z0 0 0 1 $circ_radius
# Circle will be rotated around the line
line rotation_line $x0 $y0 $z0 1 0 0
# Line rotation
for {set j 1} {$j <= $nbstep} {incr j} {
rotate rotation_line $x0 $y0 $z0 0 0 1 $angle
# Get direction for circle's rotation
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump rotation_line] full dx dy dz
# Circle rotation
copy c c_rotated
for {set k 1} {$k <= $nbstep} {incr k} {
rotate c_rotated $x0 $y0 $z0 $dx $dy $dz $angle
# Add shift of the circle along its own axis
# Get shift direction
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_rotated] full dcx dcy dcz
set dcx [expr $shift*$dcx]
set dcy [expr $shift*$dcy]
set dcz [expr $shift*$dcz]
# Make the shift
for {set t $shift_start} {$t <= $shift_end} {incr t} {
copy c_rotated c_shifted
translate c_shifted $t*$dcx $t*$dcy $t*$dcz
set log [extrema c_shifted s]
# save each circle if necessary
# copy c_shifted c_$iStep
if {![regexp "Infinite number of extremas" $log]} {
puts "Error: Extrema has not detected the parallel case on step $iStep"
} else {
regexp {Center :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_shifted] full x y z
set centers_dist [expr sqrt($x*$x + $y*$y + $z*$z)]
set real_dist [expr abs(sqrt($centers_dist*$centers_dist + $circ_radius*$circ_radius) - $sph_radius)]
set ext_dist [lindex $log end]
checkreal "Step $iStep, min distance " $ext_dist $real_dist 1.e-7 1.e-7
}
incr iStep
}
}
}
}

View File

@ -0,0 +1,93 @@
puts "======================="
puts "Test for Circle/Sphere extrema algorithm"
puts "Touch case (circle is just touching the sphere)"
puts "======================="
puts ""
# Make sphere
set x0 0.
set y0 0.
set z0 0.
set sph_radius 10.
sphere s $x0 $y0 $z0 $sph_radius
# Initially the circle will be made at the same place as sphere with different radius
# and will shifted many times to touch the sphere.
# The distance should always be close to zero.
# Number of different radius of initial circle
set nb_radius 7
# Number of circle's rotations
set nbstep 8
set angle [expr 180. / $nbstep]
# Iteration step
set iStep 1
for {set i 1} {$i < $nb_radius} {incr i} {
set circ_radius [expr $i*2.]
if {$circ_radius == $sph_radius} {
set circ_radius [expr $circ_radius + 0.1]
}
circle c $x0 $y0 $z0 0 0 1 $circ_radius
# Circle will be rotated around the line
line rotation_line $x0 $y0 $z0 1 0 0
# Line rotation
for {set j 1} {$j <= $nbstep} {incr j} {
rotate rotation_line $x0 $y0 $z0 0 0 1 $angle
# Get direction for circle's rotation
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump rotation_line] full dx dy dz
# Circle rotation
copy c c_rotated
for {set k 1} {$k <= $nbstep} {incr k} {
rotate c_rotated $x0 $y0 $z0 $dx $dy $dz $angle
# Get translation axis for the circle
regexp {XAxis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_rotated] full dxx dxy dxz
# Get rotation plane for translation line
regexp {YAxis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump c_rotated] full dyx dyy dyz
line translation_line $x0 $y0 $z0 $dxx $dxy $dxz
for {set n 1} {$n <= $nbstep} {incr n} {
rotate translation_line $x0 $y0 $z0 $dyx $dyy $dyz $angle
# Get direction for circle's translation
regexp {Axis :([-0-9.+eE]*), ([-0-9.+eE]*), ([-0-9.+eE]*)} [dump translation_line] full dtx dty dtz
# Circle's translation
copy c_rotated c_shifted
translate c_shifted $sph_radius*$dtx $sph_radius*$dty $sph_radius*$dtz
# Shift circle to touch sphere
set shift -1
repeat 2 {
copy c_shifted c_touch
translate c_touch $shift*$circ_radius*$dxx $shift*$circ_radius*$dxy $shift*$circ_radius*$dxz
set log [extrema c_touch s]
# save each circle if necessary
# copy c_touch c_$iStep
if {![regexp "ext_1" $log]} {
if {![regexp "Extrema 1 is point" $log]} {
puts "Error: Extrema has not detected the touching case on step $iStep"
} else {
puts "Check of Step $iStep, min distance OK"
}
} else {
set ext_dist [lindex [length ext_1] end]
checkreal "Step $iStep, min distance " $ext_dist 0 1.e-7 1.e-7
}
incr iStep
set shift 1
}
}
}
}
}

View File

@ -1,2 +1,3 @@
001 2dinter
002 bnd
003 extcs

View File

@ -1,6 +1,3 @@
puts "TODO OCC26677 All:An exception was caught"
puts "TODO OCC26677 All:\\*\\* Exception \\*\\*"
puts "TODO OCC26677 All:TEST INCOMPLETE"
restore [locate_data_file bug26606_002_extract_C301-full_014_offset.brep] plate
restore [locate_data_file bug26606_002_extract_C301-full_014_marker_1.brep] marker
set prlist [prj pr marker plate 0.008936 -0.001151 0.999959]

View File

@ -1,6 +1,3 @@
puts "TODO OCC26677 All:An exception was caught"
puts "TODO OCC26677 All:\\*\\* Exception \\*\\*"
puts "TODO OCC26677 All:TEST INCOMPLETE"
restore [locate_data_file bug26606_004_extract_2015-01-C37_0043_offset.brep] plate
restore [locate_data_file bug26606_004_extract_2015-01-C37_0043_marker_2.brep] marker
set prlist [prj pr marker plate 0.000490 -0.715789 0.698317]

View File

@ -1,6 +1,3 @@
puts "TODO OCC26677 All:An exception was caught"
puts "TODO OCC26677 All:\\*\\* Exception \\*\\*"
puts "TODO OCC26677 All:TEST INCOMPLETE"
restore [locate_data_file bug26606_004_extract_2015-01-C37_0077_offset.brep] plate
restore [locate_data_file bug26606_004_extract_2015-01-C37_0077_marker_2.brep] marker
set prlist [prj pr marker plate 0.000043 -0.707120 0.707094]

View File

@ -1,6 +1,3 @@
puts "TODO OCC26677 All:An exception was caught"
puts "TODO OCC26677 All:\\*\\* Exception \\*\\*"
puts "TODO OCC26677 All:TEST INCOMPLETE"
restore [locate_data_file bug26606_004_extract_2015-01-C37_0084_offset.brep] plate
restore [locate_data_file bug26606_004_extract_2015-01-C37_0084_marker_2.brep] marker
set prlist [prj pr marker plate -0.048021 -0.305504 0.950979]

View File

@ -1,6 +1,3 @@
puts "TODO OCC26677 All:An exception was caught"
puts "TODO OCC26677 All:\\*\\* Exception \\*\\*"
puts "TODO OCC26677 All:TEST INCOMPLETE"
restore [locate_data_file bug26606_005_extract_C37-full_0082_offset.brep] plate
restore [locate_data_file bug26606_005_extract_C37-full_0082_marker_2.brep] marker
set prlist [prj pr marker plate -0.008136 -0.148145 0.988932]