1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-29 14:00:49 +03:00

Patch for CR26980_1 fix

This commit is contained in:
nbv
2016-01-28 13:43:08 +03:00
parent 3b5f0ca372
commit 33a90322cf
7 changed files with 484 additions and 391 deletions

View File

@@ -524,7 +524,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
default:
{
IntPatch_PrmPrmIntersection interpp;
interpp.Perform(S1,D1,TolArc,TolTang,myFleche,myUVMaxStep);
interpp.Perform(S1,D1,TolTang,TolArc,myFleche,myUVMaxStep);
if (interpp.IsDone())
{
done = Standard_True;
@@ -1329,7 +1329,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
TolTang, ListOfPnts, RestrictLine, typs1, typs2);
}
}
}
//=======================================================================
//function : Perform
@@ -1548,7 +1548,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& theS1,
TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
}
}
}
}
//=======================================================================
//function : ParamParamPerfom
@@ -1571,10 +1571,10 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
Standard_Boolean ClearFlag = Standard_True;
if(!ListOfPnts.IsEmpty())
{
interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
ClearFlag = Standard_False;
}
interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!!
interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag); //double call!!!!!!!
}
else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
{
@@ -1587,7 +1587,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
const Standard_Real AP = Max(MU, MV);
Handle(Adaptor3d_HSurface) SS;
FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
interpp.Perform(SS,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
}
else
{
@@ -1597,7 +1597,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
const Standard_Real AP = Max(MU, MV);
Handle(Adaptor3d_HSurface) SS;
FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
interpp.Perform(theS1, theD1, SS, theD2,TolArc,TolTang,myFleche,myUVMaxStep);
interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche,myUVMaxStep);
}
}//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
else
@@ -1636,7 +1636,7 @@ void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&
Handle(Adaptor3d_HSurface) nS1 = theS1;
Handle(Adaptor3d_HSurface) nS2 = theS2;
FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
interpp.Perform(nS1,theD1,nS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
}// 'NON - COLLINEAR LINES'
}// both domains are infinite
@@ -1906,10 +1906,10 @@ void IntPatch_Intersection::
}
JoinWLines( slin, spnt, theTolTang,
theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
theS1->FirstUParameter(), theS1->LastUParameter(),
theS1->FirstVParameter(), theS1->LastVParameter(),
theS2->FirstUParameter(), theS2->LastUParameter(),
@@ -1982,7 +1982,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
else
{
IntPatch_PrmPrmIntersection interpp;
interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolArc,TolTang,myFleche,myUVMaxStep);
interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolTang,TolArc,myFleche,myUVMaxStep);
if (interpp.IsDone())
{
done = Standard_True;
@@ -1993,7 +1993,7 @@ void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)& S1,
for (; i<=nblm; i++) slin.Append(interpp.Line(i));
}
}
}
}
//======================================================================
#include <IntPatch_IType.hxx>
#include <IntPatch_LineConstructor.hxx>
@@ -2053,7 +2053,7 @@ void IntPatch_Intersection::Dump(const Standard_Integer ,
NR1[nbR1]=0;
nbR1++;
}
for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
R2[nbR2]=D2->Value();
NR2[nbR2]=0;
nbR2++;

View File

@@ -68,6 +68,192 @@ static void AddWLine(IntPatch_SequenceOfLine &theLines,
const Handle(IntPatch_WLine) &theWLine,
const Standard_Real Deflection);
static void SeveralWlinesProcessing(const Handle(Adaptor3d_HSurface)& theSurf1,
const Handle(Adaptor3d_HSurface)& theSurf2,
const IntPatch_SequenceOfLine& theSLin,
const Standard_Real* const thePeriodsArr,
const IntSurf_TypeTrans theTrans1,
const IntSurf_TypeTrans theTrans2,
const Standard_Real theTol,
const Standard_Real theMaxStepS1,
const Standard_Real theMaxStepS2,
Handle(IntPatch_WLine)& theWLline)
{
if(theSLin.Length() == 0)
return;
Standard_Real aU1 = 0.0, aV1 = 0.0, aU2 = 0.0, aV2 = 0.0;
Standard_Integer cnbV = theWLline->NbVertex();
Standard_Integer ciV;
for( ciV = 1; ciV <= cnbV; ciV++ )
{
Standard_Real pntDMin = 1.e+100;
Standard_Integer VDMin = 0;
Standard_Integer WLDMin = 0;
gp_Pnt cPV = theWLline->Vertex(ciV).Value();
theWLline->Vertex(ciV).Parameters(aU1, aV1, aU2, aV2);
const gp_Pnt2d aPCS1(aU1, aV1), aPCS2(aU2, aV2);
Standard_Integer iL;
for( iL = 1; iL <= theSLin.Length(); iL++)
{
const Handle(IntPatch_Line)& aSLine = theSLin.Value(iL);
IntPatch_IType aType = aSLine->ArcType();
if( aType != IntPatch_Walking)
continue;
const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine);
Standard_Integer tnbV = aWLine->NbVertex();
Standard_Integer tiV;
for( tiV = 1; tiV <= tnbV; tiV++ )
{
gp_Pnt tPV = aWLine->Vertex(tiV).Value();
aWLine->Vertex(tiV).Parameters(aU1, aV1, aU2, aV2);
const gp_Pnt2d aPTS1(aU1, aV1), aPTS2(aU2, aV2);
Standard_Real tDistance = cPV.Distance(tPV);
Standard_Real uRs1 = theSurf1->Surface().UResolution(tDistance);
Standard_Real vRs1 = theSurf1->Surface().VResolution(tDistance);
Standard_Real uRs2 = theSurf2->Surface().UResolution(tDistance);
Standard_Real vRs2 = theSurf2->Surface().VResolution(tDistance);
Standard_Real RmaxS1 = Max(uRs1,vRs1);
Standard_Real RmaxS2 = Max(uRs2,vRs2);
if(RmaxS1 < theMaxStepS1 && RmaxS2 < theMaxStepS2)
{
if( pntDMin > tDistance && tDistance > Precision::PConfusion())
{
const Standard_Real aSqDist1 = aPCS1.SquareDistance(aPTS1),
aSqDist2 = aPCS2.SquareDistance(aPTS2);
if((aSqDist1 < RmaxS1*RmaxS1) && (aSqDist2 < RmaxS2*RmaxS2))
{
pntDMin = tDistance;
VDMin = tiV;
WLDMin = iL;
}
}
}
}
}
if( VDMin != 0 )
{
const Handle(IntPatch_Line)& aSLine = theSLin.Value(WLDMin);
const Handle(IntPatch_WLine) aWLine = Handle(IntPatch_WLine)::DownCast(aSLine);
Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
Standard_Integer ciVpar = (Standard_Integer)theWLline->Vertex(ciV).ParameterOnLine();
Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
theWLline->Point(ciVpar).Parameters(u11,v11,u12,v12);
aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
Standard_Integer cNbP = theWLline->NbPnts();
TColStd_SequenceOfInteger VPold;
Standard_Integer iPo;
for( iPo = 1; iPo <= cnbV; iPo++ )
{
Standard_Real Po = theWLline->Vertex(iPo).ParameterOnLine();
Standard_Integer IPo = (Standard_Integer) Po;
VPold.Append(IPo);
}
Standard_Boolean removeNext = Standard_False;
Standard_Boolean removePrev = Standard_False;
if( ciV == 1)
{
Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
if(dPar > 10)
{
removeNext = Standard_True;
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
else if( ciV == cnbV)
{
Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
if(dPar > 10)
{
removePrev = Standard_True;
VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
}
}
else
{
Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
if(dParMi > 10)
{
removePrev = Standard_True;
VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
}
if(dParMa > 10)
{
removeNext = Standard_True;
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
{
if(dParMi > 10)
VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
else
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
else
{
if(dParMi > 10)
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
Standard_Integer pI = ciVpar;
Standard_Integer iP;
for( iP = 1; iP <= cNbP; iP++)
{
if( pI == iP )
{
IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, theWLline->Point(iP), thePeriodsArr);
newL2s->Add(newPnt);
}
else if(removeNext && iP == (pI + 1))
continue;
else if(removePrev && iP == (pI - 1))
continue;
else
newL2s->Add(theWLline->Point(iP));
}
IntPatch_Point newVtx;
gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
newVtx.SetValue(Pnt3dV,theTol,Standard_False);
newVtx.SetParameters(u21,v21,u22,v22);
newVtx.SetParameter(VPold.Value(ciV));
Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,theTrans1,theTrans2);
Standard_Integer iV;
for( iV = 1; iV <= cnbV; iV++ )
{
if( iV == ciV )
NWLine->AddVertex(newVtx);
else
{
IntPatch_Point theVtx = theWLline->Vertex(iV);
theVtx.SetParameter(VPold.Value(iV));
NWLine->AddVertex(theVtx);
}
}
theWLline = NWLine;
}//if( VDMin != 0 )
}//for( ciV = 1; ciV <= cnbV; ciV++ )
}
//=======================================================================
//function : DublicateOfLinesProcessing
//purpose : Decides, if rejecting current line is necessary
@@ -1606,144 +1792,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)&
wline->AddVertex(vtx);
}
Standard_Integer slinlen = SLin.Length();
if( slinlen > 0 ) {
Standard_Integer cnbV = wline->NbVertex();
Standard_Integer ciV;
for( ciV = 1; ciV <= cnbV; ciV++ ) {
Standard_Real pntDMin = 1.e+100;
Standard_Integer VDMin = 0;
Standard_Integer WLDMin = 0;
gp_Pnt cPV = wline->Vertex(ciV).Value();
Standard_Integer iL;
for( iL = 1; iL <= slinlen; iL++) {
const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
IntPatch_IType aType = aSLine->ArcType();
if( aType != IntPatch_Walking)
continue;
const Handle(IntPatch_WLine)& aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
Standard_Integer tnbV = aWLine->NbVertex();
Standard_Integer tiV;
for( tiV = 1; tiV <= tnbV; tiV++ ) {
gp_Pnt tPV = aWLine->Vertex(tiV).Value();
Standard_Real tDistance = cPV.Distance(tPV);
Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
Standard_Real RmaxS1 = Max(uRs1,vRs1);
Standard_Real RmaxS2 = Max(uRs2,vRs2);
if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4) {
if( pntDMin > tDistance && tDistance > 1.e-9) {
pntDMin = tDistance;
VDMin = tiV;
WLDMin = iL;
}
}
}
}
if( VDMin != 0 ) {
const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
const Handle(IntPatch_WLine)& aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
Standard_Integer cNbP = wline->NbPnts();
TColStd_SequenceOfInteger VPold;
Standard_Integer iPo;
for( iPo = 1; iPo <= cnbV; iPo++ ) {
Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
Standard_Integer IPo = (Standard_Integer) Po;
VPold.Append(IPo);
}
Standard_Boolean removeNext = Standard_False;
Standard_Boolean removePrev = Standard_False;
if( ciV == 1) {
Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
if(dPar > 10) {
removeNext = Standard_True;
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
else if( ciV == cnbV) {
Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
if(dPar > 10) {
removePrev = Standard_True;
VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
}
}
else {
Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
if(dParMi > 10) {
removePrev = Standard_True;
VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
}
if(dParMa > 10) {
removeNext = Standard_True;
for( iPo = (ciV+1); iPo <= cnbV; iPo++ ) {
if(dParMi > 10)
VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
else
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
else {
if(dParMi > 10)
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
Standard_Integer pI = (Standard_Integer) ciVpar;
Standard_Integer iP;
for( iP = 1; iP <= cNbP; iP++) {
if( pI == iP )
{
IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
newL2s->Add(newPnt);
}
else if(removeNext && iP == (pI + 1))
continue;
else if(removePrev && iP == (pI - 1))
continue;
else
newL2s->Add(wline->Point(iP));
}
IntPatch_Point newVtx;
gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
newVtx.SetParameters(u21,v21,u22,v22);
newVtx.SetParameter(VPold.Value(ciV));
Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
Standard_Integer iV;
for( iV = 1; iV <= cnbV; iV++ ) {
if( iV == ciV )
NWLine->AddVertex(newVtx);
else {
IntPatch_Point theVtx = wline->Vertex(iV);
theVtx.SetParameter(VPold.Value(iV));
NWLine->AddVertex(theVtx);
}
}
wline = NWLine;
}
}
}// SLin.Length > 0
SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2,
TolTang, Max(PW.MaxStep(0), PW.MaxStep(1)),
Max(PW.MaxStep(2), PW.MaxStep(3)), wline);
AddWLine(SLin, wline, Deflection);
empt = Standard_False;
@@ -2423,166 +2474,9 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
lignetrouvee = Standard_True;
Standard_Integer slinlen = SLin.Length();
if( slinlen > 0 )
{
Standard_Integer cnbV = wline->NbVertex();
Standard_Integer ciV;
for( ciV = 1; ciV <= cnbV; ciV++ )
{
Standard_Real pntDMin = 1.e+100;
Standard_Integer VDMin = 0;
Standard_Integer WLDMin = 0;
gp_Pnt cPV = wline->Vertex(ciV).Value();
Standard_Integer iL;
for( iL = 1; iL <= slinlen; iL++)
{
const Handle(IntPatch_Line)& aSLine = SLin.Value(iL);
IntPatch_IType aType = aSLine->ArcType();
if( aType != IntPatch_Walking)
continue;
const Handle(IntPatch_WLine)& aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
Standard_Integer tnbV = aWLine->NbVertex();
Standard_Integer tiV;
for( tiV = 1; tiV <= tnbV; tiV++ )
{
gp_Pnt tPV = aWLine->Vertex(tiV).Value();
Standard_Real tDistance = cPV.Distance(tPV);
Standard_Real uRs1 = Surf1->Surface().UResolution(tDistance);
Standard_Real vRs1 = Surf1->Surface().VResolution(tDistance);
Standard_Real uRs2 = Surf2->Surface().UResolution(tDistance);
Standard_Real vRs2 = Surf2->Surface().VResolution(tDistance);
Standard_Real RmaxS1 = Max(uRs1,vRs1);
Standard_Real RmaxS2 = Max(uRs2,vRs2);
if(RmaxS1 < 1.e-4 && RmaxS2 < 1.e-4)
{
if( pntDMin > tDistance && tDistance > 1.e-9)
{
pntDMin = tDistance;
VDMin = tiV;
WLDMin = iL;
}
}
}
}
if( VDMin != 0 )
{
const Handle(IntPatch_Line)& aSLine = SLin.Value(WLDMin);
const Handle(IntPatch_WLine)& aWLine = (*((Handle(IntPatch_WLine)*)&aSLine));
Standard_Integer tiVpar = (Standard_Integer)aWLine->Vertex(VDMin).ParameterOnLine();
Standard_Integer ciVpar = (Standard_Integer)wline->Vertex(ciV).ParameterOnLine();
Standard_Real u11 = 0., u12 = 0., v11 = 0., v12 = 0.;
Standard_Real u21 = 0., u22 = 0., v21 = 0., v22 = 0.;
wline->Point(ciVpar).Parameters(u11,v11,u12,v12);
aWLine->Point(tiVpar).Parameters(u21,v21,u22,v22);
Handle(IntSurf_LineOn2S) newL2s = new IntSurf_LineOn2S();
IntSurf_PntOn2S replacePnt = aWLine->Point(tiVpar);
Standard_Integer cNbP = wline->NbPnts();
TColStd_SequenceOfInteger VPold;
Standard_Integer iPo;
for( iPo = 1; iPo <= cnbV; iPo++ )
{
Standard_Real Po = wline->Vertex(iPo).ParameterOnLine();
Standard_Integer IPo = (Standard_Integer) Po;
VPold.Append(IPo);
}
Standard_Boolean removeNext = Standard_False;
Standard_Boolean removePrev = Standard_False;
if( ciV == 1)
{
Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
if(dPar > 10)
{
removeNext = Standard_True;
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
else if( ciV == cnbV)
{
Standard_Integer dPar = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
if(dPar > 10)
{
removePrev = Standard_True;
VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
}
}
else
{
Standard_Integer dParMi = Abs( VPold.Value(ciV) - VPold.Value(ciV-1));
Standard_Integer dParMa = Abs( VPold.Value(ciV) - VPold.Value(ciV+1));
if(dParMi > 10)
{
removePrev = Standard_True;
VPold.SetValue(ciV, VPold.Value(ciV) - 1 );
}
if(dParMa > 10)
{
removeNext = Standard_True;
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
{
if(dParMi > 10)
VPold.SetValue(iPo, VPold.Value(iPo) - 2 );
else
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
else
{
if(dParMi > 10)
for( iPo = (ciV+1); iPo <= cnbV; iPo++ )
VPold.SetValue(iPo, VPold.Value(iPo) - 1 );
}
}
Standard_Integer pI = ciVpar;
Standard_Integer iP;
for( iP = 1; iP <= cNbP; iP++)
{
if( pI == iP )
{
IntSurf_PntOn2S newPnt = MakeNewPoint(replacePnt, wline->Point(iP), Periods);
newL2s->Add(newPnt);
}
else if(removeNext && iP == (pI + 1))
continue;
else if(removePrev && iP == (pI - 1))
continue;
else
newL2s->Add(wline->Point(iP));
}
IntPatch_Point newVtx;
gp_Pnt Pnt3dV = aWLine->Vertex(VDMin).Value();
newVtx.SetValue(Pnt3dV,TolTang,Standard_False);
newVtx.SetParameters(u21,v21,u22,v22);
newVtx.SetParameter(VPold.Value(ciV));
Handle(IntPatch_WLine) NWLine = new IntPatch_WLine(newL2s,Standard_False,trans1,trans2);
Standard_Integer iV;
for( iV = 1; iV <= cnbV; iV++ )
{
if( iV == ciV )
NWLine->AddVertex(newVtx);
else
{
IntPatch_Point theVtx = wline->Vertex(iV);
theVtx.SetParameter(VPold.Value(iV));
NWLine->AddVertex(theVtx);
}
}
wline = NWLine;
}//if( VDMin != 0 )
}//for( ciV = 1; ciV <= cnbV; ciV++ )
}// SLin.Length > 0
SeveralWlinesProcessing(Surf1, Surf2, SLin, Periods, trans1, trans2,
TolTang, Max(PW.MaxStep(0), PW.MaxStep(1)),
Max(PW.MaxStep(2), PW.MaxStep(3)), wline);
AddWLine(SLin, wline, Deflection);
empt = Standard_False;

View File

@@ -34,10 +34,10 @@ uses
is
enumeration StatusDeflection is
PasTropGrand, PointConfondu, ArretSurPointPrecedent,
PasTropGrand, StepTooSmall, PointConfondu, ArretSurPointPrecedent,
ArretSurPoint, OK;
-- StepTooGreat, ConfusedPoint, StopOnPreviousPoint, StopOnPoint, OK
-- StepTooGreat, StepTooSmall, ConfusedPoint, StopOnPreviousPoint, StopOnPoint, OK
--class of result objects marching on a biparametric surface

View File

@@ -210,7 +210,21 @@ is
raises NotDone from StdFail
is static;
MaxStep(me ; Index : Integer from Standard)
---Purpose: Returns the point of range Index on the polyline.
-- An exception is raised if IsDone returns False.
-- An exception is raised if Index<=0 or Index>NbPoints.
returns Real from Standard
---C++: inline
raises OutOfRange from Standard
is static;
TangentAtLine(me; Index: out Integer from Standard)
@@ -250,6 +264,12 @@ is
POn2S : PntOn2S from IntSurf ) ;
---C++: inline
ComputePasInit(me : in out;
Um1, UM1, Vm1, VM1, Um2, UM2, Vm2, VM2, Um1p, UM1p, Vm1p, VM1p, Um2p, UM2p, Vm2p, VM2p, Increment, tolconf: Real from Standard)
is protected;
ExtendLineInCommonZone(me: in out; theChoixIso: ConstIsoparametric from IntImp;
theDirectionFlag: Boolean from Standard)
returns Boolean from Standard
@@ -317,9 +337,11 @@ fields
fleche : Real from Standard; -- max possible vector
pasMax : Real from Standard; -- max possible uv ratio
tolconf : Real from Standard; -- tol of confusion of 2 points
myTolTang : Real from Standard;
pasuv : Real from Standard[4];-- uv step on squares
pasSav : Real from Standard[4];-- first saved step
pasInit : Real from Standard[4];-- saving of steps
myStepMin : Real from Standard[4];
Um1 : Real from Standard;
UM1 : Real from Standard;

View File

@@ -40,20 +40,28 @@
// estimate of max step : To avoid abrupt changes
// during change of isos
//==================================================================================
void ComputePasInit(Standard_Real *pasuv,
Standard_Real Um1,Standard_Real UM1,
Standard_Real Vm1,Standard_Real VM1,
Standard_Real Um2,Standard_Real UM2,
Standard_Real Vm2,Standard_Real VM2,
Standard_Real _Um1,Standard_Real _UM1,
Standard_Real _Vm1,Standard_Real _VM1,
Standard_Real _Um2,Standard_Real _UM2,
Standard_Real _Vm2,Standard_Real _VM2,
const Handle(Adaptor3d_HSurface)& Caro1,
const Handle(Adaptor3d_HSurface)& Caro2,
const Standard_Real Increment,
const Standard_Real tolconf)
{
void IntWalk_PWalking::ComputePasInit(const Standard_Real Um1,
const Standard_Real UM1,
const Standard_Real Vm1,
const Standard_Real VM1,
const Standard_Real Um2,
const Standard_Real UM2,
const Standard_Real Vm2,
const Standard_Real VM2,
const Standard_Real _Um1,
const Standard_Real _UM1,
const Standard_Real _Vm1,
const Standard_Real _VM1,
const Standard_Real _Um2,
const Standard_Real _UM2,
const Standard_Real _Vm2,
const Standard_Real _VM2,
const Standard_Real Increment,
const Standard_Real tolconf)
{
const Handle(Adaptor3d_HSurface)& Caro1 = myIntersectionOn2S.Function().AuxillarSurface1();
const Handle(Adaptor3d_HSurface)& Caro2 = myIntersectionOn2S.Function().AuxillarSurface2();
Standard_Real du1=Abs(UM1-Um1);
Standard_Real dv1=Abs(VM1-Vm1);
Standard_Real du2=Abs(UM2-Um2);
@@ -72,24 +80,25 @@ void ComputePasInit(Standard_Real *pasuv,
if(_du2<1e50 && du2<0.01*_du2) du2=0.01*_du2;
if(_dv2<1e50 && dv2<0.01*_dv2) dv2=0.01*_dv2;
pasuv[0]=Increment*du1;
pasuv[1]=Increment*dv1;
pasuv[2]=Increment*du2;
pasuv[3]=Increment*dv2;
pasuv[0]=Max(Increment*du1, pasuv[0]);
pasuv[1]=Max(Increment*dv1, pasuv[1]);
pasuv[2]=Max(Increment*du2, pasuv[2]);
pasuv[3]=Max(Increment*dv2, pasuv[3]);
Standard_Real ResoU1tol = Adaptor3d_HSurfaceTool::UResolution(Caro1, tolconf);
Standard_Real ResoV1tol = Adaptor3d_HSurfaceTool::VResolution(Caro1, tolconf);
Standard_Real ResoU2tol = Adaptor3d_HSurfaceTool::UResolution(Caro2, tolconf);
Standard_Real ResoV2tol = Adaptor3d_HSurfaceTool::VResolution(Caro2, tolconf);
if (pasuv[0] < 2*ResoU1tol)
pasuv[0] = 2*ResoU1tol;
if (pasuv[1] < 2*ResoV1tol)
pasuv[1] = 2*ResoV1tol;
if (pasuv[2] < 2*ResoU2tol)
pasuv[2] = 2*ResoU2tol;
if (pasuv[3] < 2*ResoV2tol)
pasuv[3] = 2*ResoV2tol;
myStepMin[0] = Max(myStepMin[0], 2.0*ResoU1tol);
myStepMin[1] = Max(myStepMin[1], 2.0*ResoV1tol);
myStepMin[2] = Max(myStepMin[2], 2.0*ResoU2tol);
myStepMin[3] = Max(myStepMin[3], 2.0*ResoV2tol);
for(Standard_Integer i = 0; i < 4; i++)
{
pasuv[i]=Max(myStepMin[i], pasuv[i]);
}
}
//=======================================================================
@@ -268,6 +277,7 @@ done(Standard_True),
close(Standard_False),
fleche(Deflection),
tolconf(Epsilon),
myTolTang(TolTangency),
sensCheminement(1),
myIntersectionOn2S(Caro1,Caro2,TolTangency),
STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
@@ -378,6 +388,11 @@ STATIC_PRECEDENT_INFLEXION(0)
}
}
myStepMin[0] = 100.0*ResoU1;
myStepMin[1] = 100.0*ResoV1;
myStepMin[2] = 100.0*ResoU2;
myStepMin[3] = 100.0*ResoV2;
//-- ComputePasInit(pasuv,Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2);
for (Standard_Integer i = 0; i<=3;i++) {
@@ -408,6 +423,7 @@ done(Standard_True),
close(Standard_False),
fleche(Deflection),
tolconf(Epsilon),
myTolTang(TolTangency),
sensCheminement(1),
myIntersectionOn2S(Caro1,Caro2,TolTangency),
STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0),
@@ -544,6 +560,12 @@ STATIC_PRECEDENT_INFLEXION(0)
if(ResoV1>0.0001*pasuv[1]) ResoV1=0.00001*pasuv[1];
if(ResoU2>0.0001*pasuv[2]) ResoU2=0.00001*pasuv[2];
if(ResoV2>0.0001*pasuv[3]) ResoV2=0.00001*pasuv[3];
myStepMin[0] = 100.0*ResoU1;
myStepMin[1] = 100.0*ResoV1;
myStepMin[2] = 100.0*ResoU2;
myStepMin[3] = 100.0*ResoV2;
//
TColStd_Array1OfReal Par(1,4);
Par(1) = U1;
@@ -623,6 +645,7 @@ static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_HSurface)& theS
const Standard_Real theV10,
const Standard_Real theU20,
const Standard_Real theV20,
const Standard_Real theToler,
const Standard_Real theArrStep[])
{
{
@@ -646,7 +669,8 @@ static Standard_Boolean IsTangentExtCheck(const Handle(Adaptor3d_HSurface)& theS
}
}
const Standard_Real aSQToler = 4.0e-14;
//For two faces (2^2 = 4)
const Standard_Real aSQToler = 4.0*theToler*theToler;
const Standard_Integer aNbItems = 4;
const Standard_Real aParUS1[aNbItems] = { theU10 + theArrStep[0],
theU10 - theArrStep[0],
@@ -718,22 +742,9 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
const Standard_Real ULast2 = Adaptor3d_HSurfaceTool::LastUParameter (Caro2);
const Standard_Real VLast2 = Adaptor3d_HSurfaceTool::LastVParameter (Caro2);
//
ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax,tolconf);
//
if(pasuv[0]<100.0*ResoU1) {
pasuv[0]=100.0*ResoU1;
}
if(pasuv[1]<100.0*ResoV1) {
pasuv[1]=100.0*ResoV1;
}
if(pasuv[2]<100.0*ResoU2) {
pasuv[2]=100.0*ResoU2;
}
if(pasuv[3]<100.0*ResoV2) {
pasuv[3]=100.0*ResoV2;
}
//
ComputePasInit(u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,pasMax+pasMax,tolconf);
for (Standard_Integer i=0; i<4; ++i)
{
if(pasuv[i]>10)
@@ -807,7 +818,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), pasuv))
if(IsTangentExtCheck(Caro1, Caro2, Param(1), Param(2), Param(3), Param(4), myTolTang, pasuv))
return;
AddAPoint(line,previousPoint);
@@ -1166,27 +1177,9 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
{
pastroppetit=Standard_True;
if(pasuv[0]<pasInit[0])
for(Standard_Integer i = 0; i < 4; i++)
{
pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
pastroppetit=Standard_False;
}
if(pasuv[1]<pasInit[1])
{
pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
pastroppetit=Standard_False;
}
if(pasuv[2]<pasInit[2])
{
pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
pastroppetit=Standard_False;
}
if(pasuv[3]<pasInit[3])
{
pasuv[3]+=(pasInit[3]-pasuv[3])*0.25;
pasuv[i]+=(pasInit[i]-pasuv[i])*0.25;
pastroppetit=Standard_False;
}
@@ -1211,6 +1204,32 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
break;
}
case IntWalk_StepTooSmall:
{
Standard_Boolean hasStepBeenIncreased = Standard_False;
for(Standard_Integer i = 0; i < 4; i++)
{
const Standard_Real aNewStep = Min(1.5*pasuv[i], pasInit[i]);
if(aNewStep > pasuv[i])
{
pasuv[i] = aNewStep;
hasStepBeenIncreased = Standard_True;
}
}
if(hasStepBeenIncreased)
{
Param(1)=SvParam[0];
Param(2)=SvParam[1];
Param(3)=SvParam[2];
Param(4)=SvParam[3];
LevelOfIterWithoutAppend = 0;
break;
}
}
case IntWalk_OK:
case IntWalk_ArretSurPoint://006
{
@@ -1299,6 +1318,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
if(RejectIndex >= RejectIndexMAX)
{
Arrive = Standard_True;
break;
}
@@ -1386,6 +1406,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
if(RejectIndex >= RejectIndexMAX)
{
Arrive = Standard_True;
break;
}
@@ -1619,6 +1640,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
if(RejectIndex >= RejectIndexMAX)
{
Arrive = Standard_True;
break;
}
@@ -2104,7 +2126,7 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
aS1 = theASurf1->Surface().BSpline();
break;
default:
return Standard_True;
return Standard_True;
}
switch(theASurf2->GetType())
@@ -2116,7 +2138,7 @@ DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1,
aS2 = theASurf2->Surface().BSpline();
break;
default:
return Standard_True;
return Standard_True;
}
Standard_Boolean aStatus = Standard_False;
@@ -2821,7 +2843,7 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
}
IntWalk_StatusDeflection Status = IntWalk_OK;
Standard_Real FlecheCourante ,Ratio;
Standard_Real FlecheCourante , Ratio = 1.0;
const IntSurf_PntOn2S& CurrentPoint = myIntersectionOn2S.Point();
@@ -2834,10 +2856,12 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
const gp_Dir& TgCourante = myIntersectionOn2S.Direction();
const Standard_Real aCosBetweenTangent = TgCourante.Dot(previousd);
//==================================================================================
//========= R i s k o f i n f l e x i o n p o i n t ============
//==================================================================================
if (TgCourante.Dot(previousd)<0) {
if (aCosBetweenTangent < 0) {
//------------------------------------------------------------
//-- Risk of inflexion point : Divide the step by 2
//-- Initialize STATIC_PRECEDENT_INFLEXION so that
@@ -2855,7 +2879,6 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
else
return IntWalk_PasTropGrand;
}
else {
if(STATIC_PRECEDENT_INFLEXION > 0) {
STATIC_PRECEDENT_INFLEXION -- ;
@@ -2867,11 +2890,11 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
//========= D e t e c t c o n f u s e d P o in t s ===========
//==================================================================================
Standard_Real Dist = previousPoint.Value().
const Standard_Real aSqDist = previousPoint.Value().
SquareDistance(CurrentPoint.Value());
if (Dist < tolconf*tolconf ) {
if (aSqDist < tolconf*tolconf ) {
pasuv[0] = Max(5.*ResoU1,Min(1.5*pasuv[0],pasInit[0]));
pasuv[1] = Max(5.*ResoV1,Min(1.5*pasuv[1],pasInit[1]));
pasuv[2] = Max(5.*ResoU2,Min(1.5*pasuv[2],pasInit[2]));
@@ -2994,7 +3017,7 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
//-- Estimate of the vector --
//---------------------------------------
FlecheCourante =
Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*Dist))/8.;
Sqrt(Abs((previousd.XYZ()-TgCourante.XYZ()).SquareModulus()*aSqDist))/8.;
if ( FlecheCourante<= fleche*0.5) { //-- Current step too small
if(FlecheCourante>1e-16) {
@@ -3061,10 +3084,94 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection()
Ratio = 0.75 * (fleche / FlecheCourante);
}
}
pasuv[0] = Max(5.*ResoU1,Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
pasuv[1] = Max(5.*ResoV1,Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
pasuv[2] = Max(5.*ResoU2,Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
pasuv[3] = Max(5.*ResoV2,Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
if(Status != IntWalk_PointConfondu)
{
//Here, aCosBetweenTangent >= 0.0 definitely.
/*
Brief algorithm description.
We have two (not-coincindent) intersection point (P1 and P2). In every point,
vector of tangent (to the intersection curve) is known (vectors T1 and T2).
Basing on these data, we create osculating circle.
* - arc of osculating circle
* *
P1 x----------x P2
/ \
/ \
Vec(T1) Vec(T2)
Let me draw your attention to the following facts:
1. Vectors T1 and T2 direct FROM (not TO) points P1 and P2. Therefore,
one of previously computed vector should be reversed.
In this case, the absolute (!) value of the deflection between the arc of
the osculating circle and the P1P2 segment can be computed as follows:
e = d*(1-sin(B/2))/(2*cos(B/2)), (1)
where d is the length of P1P2 segment, B is the angle between vectors T1 and T2.
At that,
pi/2 <= B <= pi,
cos(B/2) >= 0,
sin(B/2) > 0,
sin(B) > 0,
cos(B) < 0.
Later, the normal state of algorithm work is (as we apply)
tolconf/2 <= e <= tolconf.
In this case, we keep previous step.
If e < tolconf/2 then the local curvature of the intersection curve is small.
As result, the step should be increased.
If e > tolconf then the step is too big. Therefore, we should decrease one.
Condition (1) is equivalent to
cos(B) = 1 - 2*(1-2/(1+(d/(2*e))^2))^2 = Fd(e),
where Fd(e) is some function with parameter "deflection".
Let mean that Fd(e) is increasing function, i.e. the greater cos(B)
the greater real deflection e.
*/
//When Deflection is equal to tolconf
const Standard_Real anInvSqAbsArcDeflMax = 0.25*aSqDist/(tolconf*tolconf);
//When Deflection is equal to tolconf/2
const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax;
const Standard_Real aThresholdCosMin = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin);
const Standard_Real aThresholdCosMax = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMax);
if((Status != IntWalk_PasTropGrand) && (aCosBetweenTangent < 2.0*aThresholdCosMax*aThresholdCosMax - 1.0))
{ // I.e. cos(B) >= Fd(tolconf).
// Consequently, real deflection is greater than tolconf (too big) ==> decrease step
pasuv[0]*=0.5; pasuv[1]*=0.5; pasuv[2]*=0.5; pasuv[3]*=0.5;
return IntWalk_PasTropGrand;
}
if(aCosBetweenTangent > 2.0*aThresholdCosMin*aThresholdCosMin - 1.0)
{ //I.e. cos(B) <= Fd(tolconf/2)
// Consequently, real deflection is less than tolconf/2 (too small) ==> increase step
pasuv[0] = Max(pasuv[0], AbsDu1);
pasuv[1] = Max(pasuv[1], AbsDv1);
pasuv[2] = Max(pasuv[2], AbsDu2);
pasuv[3] = Max(pasuv[3], AbsDv2);
pasInit[0] = Max(pasInit[0], AbsDu1);
pasInit[1] = Max(pasInit[1], AbsDv1);
pasInit[2] = Max(pasInit[2], AbsDu2);
pasInit[3] = Max(pasInit[3], AbsDv2);
return IntWalk_StepTooSmall;
}
}
pasuv[0] = Max(myStepMin[0],Min(Min(Ratio*AbsDu1,pasuv[0]),pasInit[0]));
pasuv[1] = Max(myStepMin[1],Min(Min(Ratio*AbsDv1,pasuv[1]),pasInit[1]));
pasuv[2] = Max(myStepMin[2],Min(Min(Ratio*AbsDu2,pasuv[2]),pasInit[2]));
pasuv[3] = Max(myStepMin[3],Min(Min(Ratio*AbsDv2,pasuv[3]),pasInit[3]));
if(Status == IntWalk_OK) STATIC_BLOCAGE_SUR_PAS_TROP_GRAND=0;
return Status;
}

View File

@@ -62,6 +62,12 @@ inline const gp_Dir& IntWalk_PWalking::TangentAtLine
return tgdir;
}
inline Standard_Real IntWalk_PWalking::MaxStep(Standard_Integer theIndex) const
{
Standard_OutOfRange_Raise_if((theIndex < 0) || (theIndex > 3), "");
return pasInit[theIndex];
}
#define REGLAGE 0
inline void IntWalk_PWalking::AddAPoint(Handle(IntSurf_LineOn2S)& theLine,

View File

@@ -0,0 +1,64 @@
puts "========"
puts "OCC26980"
puts "========"
puts ""
#################################
# Intersection part of Boolean algorithm spends much system time and system memory
#################################
cpulimit 5000
set max_time 120
set mem_max_wsetpeak 700000000
bclearobjects;
bcleartools;
restore [locate_data_file bug26980-cmp.brep] cmp
puts [nbshapes cmp -t]
eval baddobjects [explode cmp]
dchrono cr reset
dchrono cr start
bfillds
bbuild result
dchrono cr stop
set mem_wsetpeak [meminfo wsetpeak]
if { ${mem_wsetpeak} > ${mem_max_wsetpeak}} {
puts "Error : there is memory problem (${mem_wsetpeak} MBytes has been allocated)"
}
set chrono_info [dchrono cr show]
regexp {CPU user time: ([-0-9.+eE]+) seconds} $chrono_info full CPU_time
if { $CPU_time > ${max_time} } {
puts "CPU user time of Boolean operation is more than ${max_time} seconds - Error"
} else {
puts "CPU user time of Boolean operation is less than ${max_time} seconds - OK"
}
set nbshapes_expected "
VERTEX : 365
EDGE : 793
WIRE : 531
FACE : 531
SHELL : 102
SOLID : 101
COMPSOLID : 0
COMPOUND : 1
SHAPE : 2424
"
checknbshapes result -ref ${nbshapes_expected} -t
smallview
donly result
fit
set 2dviewer 1