// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
+#include <IntPatch_Intersection.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <Adaptor3d_TopolTool.hxx>
#include <IntPatch_GLine.hxx>
#include <IntPatch_ImpImpIntersection.hxx>
#include <IntPatch_ImpPrmIntersection.hxx>
-#include <IntPatch_Intersection.hxx>
#include <IntPatch_Line.hxx>
#include <IntPatch_Point.hxx>
#include <IntPatch_PrmPrmIntersection.hxx>
#include <IntPatch_RLine.hxx>
#include <IntPatch_WLine.hxx>
+#include <IntPatch_WLineTool.hxx>
#include <IntSurf_Quadric.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
+#include <IntPatch_LineConstructor.hxx>
#include <stdio.h>
#define DEBUG 0
static const Standard_Integer aNbPointsInALine = 200;
-//=======================================================================
-//function : MinMax
-//purpose : Replaces theParMIN = MIN(theParMIN, theParMAX),
-// theParMAX = MAX(theParMIN, theParMAX).
-//=======================================================================
-static inline void MinMax(Standard_Real& theParMIN, Standard_Real& theParMAX)
-{
- if(theParMIN > theParMAX)
- {
- const Standard_Real aTmp = theParMAX;
- theParMAX = theParMIN;
- theParMIN = aTmp;
- }
-}
-
-//=======================================================================
-//function : IsSeam
-//purpose : Returns:
-// 0 - if interval [theU1, theU2] does not intersect the "seam-edge"
-// or if "seam-edge" do not exist;
-// 1 - if interval (theU1, theU2) intersect the "seam-edge".
-// 2 - if theU1 or/and theU2 lie ON the "seam-edge"
-//
-//ATTENTION!!!
-// If (theU1 == theU2) then this function will return only both 0 or 2.
-//=======================================================================
-static Standard_Integer IsSeam( const Standard_Real theU1,
- const Standard_Real theU2,
- const Standard_Real thePeriod)
-{
- if(IsEqual(thePeriod, 0.0))
- return 0;
-
- //If interval [theU1, theU2] intersect seam-edge then there exists an integer
- //number N such as
- // (theU1 <= T*N <= theU2) <=> (theU1/T <= N <= theU2/T),
- //where T is the period.
- //I.e. the inerval [theU1/T, theU2/T] must contain at least one
- //integer number. In this case, Floor(theU1/T) and Floor(theU2/T)
- //return different values or theU1/T is strictly integer number.
- //Examples:
- // 1. theU1/T==2.8, theU2/T==3.5 => Floor(theU1/T) == 2, Floor(theU2/T) == 3.
- // 2. theU1/T==2.0, theU2/T==2.6 => Floor(theU1/T) == Floor(theU2/T) == 2.
-
- const Standard_Real aVal1 = theU1/thePeriod,
- aVal2 = theU2/thePeriod;
- const Standard_Integer aPar1 = static_cast<Standard_Integer>(Floor(aVal1));
- const Standard_Integer aPar2 = static_cast<Standard_Integer>(Floor(aVal2));
- if(aPar1 != aPar2)
- {//Interval (theU1, theU2] intersects seam-edge
- if(IsEqual(aVal2, static_cast<Standard_Real>(aPar2)))
- {//aVal2 is an integer number => theU2 lies ON the "seam-edge"
- return 2;
- }
-
- return 1;
- }
-
- //Here, aPar1 == aPar2.
-
- if(IsEqual(aVal1, static_cast<Standard_Real>(aPar1)))
- {//aVal1 is an integer number => theU1 lies ON the "seam-edge"
- return 2;
- }
-
- //If aVal2 is a true integer number then always (aPar1 != aPar2).
-
- return 0;
-}
-
-//=======================================================================
-//function : IsSeamOrBound
-//purpose : Returns TRUE if segment [thePtf, thePtl] intersects "seam-edge"
-// (if it exist) or surface boundaries and both thePtf and thePtl do
-// not match "seam-edge" or boundaries.
-// Point thePtmid lies in this segment. If thePtmid match
-// "seam-edge" or boundaries strictly (without any tolerance) then
-// the function will return TRUE.
-// See comments in function body for detail information.
-//=======================================================================
-static Standard_Boolean IsSeamOrBound(const IntSurf_PntOn2S& thePtf,
- const IntSurf_PntOn2S& thePtl,
- const IntSurf_PntOn2S& thePtmid,
- const Standard_Real theU1Period,
- const Standard_Real theU2Period,
- const Standard_Real theV1Period,
- const Standard_Real theV2Period,
- const Standard_Real theUfSurf1,
- const Standard_Real theUlSurf1,
- const Standard_Real theVfSurf1,
- const Standard_Real theVlSurf1,
- const Standard_Real theUfSurf2,
- const Standard_Real theUlSurf2,
- const Standard_Real theVfSurf2,
- const Standard_Real theVlSurf2)
-{
- Standard_Real aU11 = 0.0, aU12 = 0.0, aV11 = 0.0, aV12 = 0.0;
- Standard_Real aU21 = 0.0, aU22 = 0.0, aV21 = 0.0, aV22 = 0.0;
- thePtf.Parameters(aU11, aV11, aU12, aV12);
- thePtl.Parameters(aU21, aV21, aU22, aV22);
-
- MinMax(aU11, aU21);
- MinMax(aV11, aV21);
- MinMax(aU12, aU22);
- MinMax(aV12, aV22);
-
- if((aU11 - theUfSurf1)*(aU21 - theUfSurf1) < 0.0)
- {//Interval [aU11, aU21] intersects theUfSurf1
- return Standard_True;
- }
-
- if((aU11 - theUlSurf1)*(aU21 - theUlSurf1) < 0.0)
- {//Interval [aU11, aU21] intersects theUlSurf1
- return Standard_True;
- }
-
- if((aV11 - theVfSurf1)*(aV21 - theVfSurf1) < 0.0)
- {//Interval [aV11, aV21] intersects theVfSurf1
- return Standard_True;
- }
-
- if((aV11 - theVlSurf1)*(aV21 - theVlSurf1) < 0.0)
- {//Interval [aV11, aV21] intersects theVlSurf1
- return Standard_True;
- }
-
- if((aU12 - theUfSurf2)*(aU22 - theUfSurf2) < 0.0)
- {//Interval [aU12, aU22] intersects theUfSurf2
- return Standard_True;
- }
-
- if((aU12 - theUlSurf2)*(aU22 - theUlSurf2) < 0.0)
- {//Interval [aU12, aU22] intersects theUlSurf2
- return Standard_True;
- }
-
- if((aV12 - theVfSurf2)*(aV22 - theVfSurf2) < 0.0)
- {//Interval [aV12, aV22] intersects theVfSurf2
- return Standard_True;
- }
-
- if((aV12 - theVlSurf2)*(aV22 - theVlSurf2) < 0.0)
- {//Interval [aV12, aV22] intersects theVlSurf2
- return Standard_True;
- }
-
- if(IsSeam(aU11, aU21, theU1Period))
- return Standard_True;
-
- if(IsSeam(aV11, aV21, theV1Period))
- return Standard_True;
-
- if(IsSeam(aU12, aU22, theU2Period))
- return Standard_True;
-
- if(IsSeam(aV12, aV22, theV2Period))
- return Standard_True;
-
- /*
- The segment [thePtf, thePtl] does not intersect the boundaries and
- the seam-edge of the surfaces.
- Nevertheless, following situation is possible:
-
- seam or
- bound
- |
- thePtf * |
- |
- * thePtmid
- thePtl * |
- |
-
- This case must be processed, too.
- */
-
- Standard_Real aU1 = 0.0, aU2 = 0.0, aV1 = 0.0, aV2 = 0.0;
- thePtmid.Parameters(aU1, aV1, aU2, aV2);
-
- if(IsEqual(aU1, theUfSurf1) || IsEqual(aU1, theUlSurf1))
- return Standard_True;
-
- if(IsEqual(aU2, theUfSurf2) || IsEqual(aU2, theUlSurf2))
- return Standard_True;
-
- if(IsEqual(aV1, theVfSurf1) || IsEqual(aV1, theVlSurf1))
- return Standard_True;
-
- if(IsEqual(aV2, theVfSurf2) || IsEqual(aV2, theVlSurf2))
- return Standard_True;
-
- if(IsSeam(aU1, aU1, theU1Period))
- return Standard_True;
-
- if(IsSeam(aU2, aU2, theU2Period))
- return Standard_True;
-
- if(IsSeam(aV1, aV1, theV1Period))
- return Standard_True;
-
- if(IsSeam(aV2, aV2, theV2Period))
- return Standard_True;
-
- return Standard_False;
-}
-
-//=======================================================================
-//function : JoinWLines
-//purpose : joins all WLines from theSlin to one if it is possible and
-// records the result into theSlin again.
-// Lines will be kept to be splitted if:
-// a) they are separated (has no common points);
-// b) resulted line (after joining) go through
-// seam-edges or surface boundaries.
-//
-// In addition, if points in theSPnt lies at least in one of
-// the line in theSlin, this point will be deleted.
-//=======================================================================
-static void JoinWLines(IntPatch_SequenceOfLine& theSlin,
- IntPatch_SequenceOfPoint& theSPnt,
- const Standard_Real theTol3D,
- const Standard_Real theU1Period,
- const Standard_Real theU2Period,
- const Standard_Real theV1Period,
- const Standard_Real theV2Period,
- const Standard_Real theUfSurf1,
- const Standard_Real theUlSurf1,
- const Standard_Real theVfSurf1,
- const Standard_Real theVlSurf1,
- const Standard_Real theUfSurf2,
- const Standard_Real theUlSurf2,
- const Standard_Real theVfSurf2,
- const Standard_Real theVlSurf2)
-{
- if(theSlin.Length() == 0)
- return;
-
- for(Standard_Integer aNumOfLine1 = 1; aNumOfLine1 <= theSlin.Length(); aNumOfLine1++)
- {
- Handle(IntPatch_WLine) aWLine1 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine1)));
-
- if(aWLine1.IsNull())
- {//We must have failed to join not-point-lines
- return;
- }
-
- const Standard_Integer aNbPntsWL1 = aWLine1->NbPnts();
- const IntSurf_PntOn2S& aPntFW1 = aWLine1->Point(1);
- const IntSurf_PntOn2S& aPntLW1 = aWLine1->Point(aNbPntsWL1);
-
- for(Standard_Integer aNPt = 1; aNPt <= theSPnt.Length(); aNPt++)
- {
- const IntSurf_PntOn2S aPntCur = theSPnt.Value(aNPt).PntOn2S();
-
- if( aPntCur.IsSame(aPntFW1, Precision::Confusion()) ||
- aPntCur.IsSame(aPntLW1, Precision::Confusion()))
- {
- theSPnt.Remove(aNPt);
- aNPt--;
- }
- }
-
- Standard_Boolean hasBeenRemoved = Standard_False;
- for(Standard_Integer aNumOfLine2 = aNumOfLine1 + 1; aNumOfLine2 <= theSlin.Length(); aNumOfLine2++)
- {
- Handle(IntPatch_WLine) aWLine2 (Handle(IntPatch_WLine)::DownCast(theSlin.Value(aNumOfLine2)));
-
- const Standard_Integer aNbPntsWL2 = aWLine2->NbPnts();
-
- const IntSurf_PntOn2S& aPntFWL1 = aWLine1->Point(1);
- const IntSurf_PntOn2S& aPntLWL1 = aWLine1->Point(aNbPntsWL1);
-
- const IntSurf_PntOn2S& aPntFWL2 = aWLine2->Point(1);
- const IntSurf_PntOn2S& aPntLWL2 = aWLine2->Point(aNbPntsWL2);
-
- if(aPntFWL1.IsSame(aPntFWL2, Precision::Confusion()))
- {
- const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
- const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
- if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period,
- theV1Period, theV2Period, theUfSurf1, theUlSurf1,
- theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
- theVfSurf2, theVlSurf2))
- {
- aWLine1->ClearVertexes();
- for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
- {
- const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
- aWLine1->Curve()->InsertBefore(1, aPt);
- }
-
- aWLine1->ComputeVertexParameters(theTol3D);
-
- theSlin.Remove(aNumOfLine2);
- aNumOfLine2--;
- hasBeenRemoved = Standard_True;
-
- continue;
- }
- }
-
- if(aPntFWL1.IsSame(aPntLWL2, Precision::Confusion()))
- {
- const IntSurf_PntOn2S& aPt1 = aWLine1->Point(2);
- const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
- if(!IsSeamOrBound(aPt1, aPt2, aPntFWL1, theU1Period, theU2Period,
- theV1Period, theV2Period, theUfSurf1, theUlSurf1,
- theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
- theVfSurf2, theVlSurf2))
- {
- aWLine1->ClearVertexes();
- for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
- {
- const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
- aWLine1->Curve()->InsertBefore(1, aPt);
- }
-
- aWLine1->ComputeVertexParameters(theTol3D);
-
- theSlin.Remove(aNumOfLine2);
- aNumOfLine2--;
- hasBeenRemoved = Standard_True;
-
- continue;
- }
- }
-
- if(aPntLWL1.IsSame(aPntFWL2, Precision::Confusion()))
- {
- const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
- const IntSurf_PntOn2S& aPt2 = aWLine2->Point(2);
- if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period,
- theV1Period, theV2Period, theUfSurf1, theUlSurf1,
- theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
- theVfSurf2, theVlSurf2))
- {
- aWLine1->ClearVertexes();
- for(Standard_Integer aNPt = 1; aNPt <= aNbPntsWL2; aNPt++)
- {
- const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
- aWLine1->Curve()->Add(aPt);
- }
-
- aWLine1->ComputeVertexParameters(theTol3D);
-
- theSlin.Remove(aNumOfLine2);
- aNumOfLine2--;
- hasBeenRemoved = Standard_True;
-
- continue;
- }
- }
-
- if(aPntLWL1.IsSame(aPntLWL2, Precision::Confusion()))
- {
- const IntSurf_PntOn2S& aPt1 = aWLine1->Point(aNbPntsWL1-1);
- const IntSurf_PntOn2S& aPt2 = aWLine2->Point(aNbPntsWL2-1);
- if(!IsSeamOrBound(aPt1, aPt2, aPntLWL1, theU1Period, theU2Period,
- theV1Period, theV2Period, theUfSurf1, theUlSurf1,
- theVfSurf1, theVlSurf1, theUfSurf2, theUlSurf2,
- theVfSurf2, theVlSurf2))
- {
- aWLine1->ClearVertexes();
- for(Standard_Integer aNPt = aNbPntsWL2; aNPt >= 1; aNPt--)
- {
- const IntSurf_PntOn2S& aPt = aWLine2->Point(aNPt);
- aWLine1->Curve()->Add(aPt);
- }
-
- aWLine1->ComputeVertexParameters(theTol3D);
-
- theSlin.Remove(aNumOfLine2);
- aNumOfLine2--;
- hasBeenRemoved = Standard_True;
-
- continue;
- }
- }
- }
-
- if(hasBeenRemoved)
- aNumOfLine1--;
- }
-}
-
//======================================================================
// function: SequenceOfLine
//======================================================================
const Standard_Real TolArc,
const Standard_Real TolTang,
const Standard_Boolean isGeomInt,
- const Standard_Boolean theIsReqToKeepRLine)
+ const Standard_Boolean theIsReqToKeepRLine,
+ const Standard_Boolean theIsReqToPostWLProc)
{
myTolArc = TolArc;
myTolTang = TolTang;
ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
TolTang, ListOfPnts, RestrictLine, typs1, typs2);
}
+
+ if(!theIsReqToPostWLProc)
+ return;
+
+ for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+ {
+ Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+ if(aWL.IsNull())
+ continue;
+
+ Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+
+ if(aRW.IsNull())
+ continue;
+
+ slin.InsertAfter(i, aRW);
+ slin.Remove(i);
+ }
}
//=======================================================================
const Standard_Real TolTang,
IntSurf_ListOfPntOn2S& ListOfPnts,
const Standard_Boolean RestrictLine,
- const Standard_Boolean isGeomInt)
+ const Standard_Boolean isGeomInt,
+ const Standard_Boolean theIsReqToKeepRLine,
+ const Standard_Boolean theIsReqToPostWLProc)
{
myTolArc = TolArc;
myTolTang = TolTang;
if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite())
{
GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc,
- TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+ TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
}
else
{
GeomGeomPerfomTrimSurf(theS1, theD1, theS2, theD2,
- TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
+ TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
}
}
+
+ if(!theIsReqToPostWLProc)
+ return;
+
+ for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+ {
+ Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+ if(aWL.IsNull())
+ continue;
+
+ Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
+
+ if(aRW.IsNull())
+ continue;
+
+ slin.InsertAfter(i, aRW);
+ slin.Remove(i);
+ }
}
//=======================================================================
spnt.Append(aPoint);
}
- 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->FirstUParameter(), theS1->LastUParameter(),
- theS1->FirstVParameter(), theS1->LastVParameter(),
- theS2->FirstUParameter(), theS2->LastUParameter(),
- theS2->FirstVParameter(), theS2->LastVParameter());
+ IntPatch_WLineTool::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->FirstUParameter(),
+ theS1->LastUParameter(),
+ theS1->FirstVParameter(),
+ theS1->LastVParameter(),
+ theS2->FirstUParameter(),
+ theS2->LastUParameter(),
+ theS2->FirstVParameter(),
+ theS2->LastVParameter());
}
}
}
for (; i<=nblm; i++) slin.Append(interpp.Line(i));
}
}
+
+ for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
+ {
+ Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
+
+ if(aWL.IsNull())
+ continue;
+
+ Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
+
+ if(aRW.IsNull())
+ continue;
+
+ slin.InsertAfter(i, aRW);
+ slin.Remove(i);
+ }
}
-//======================================================================
-#include <IntPatch_IType.hxx>
-#include <IntPatch_LineConstructor.hxx>
-#include <Adaptor2d_HCurve2d.hxx>
-#include <Geom_Curve.hxx>
-#define MAXR 200
-
-
-//void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
-// Handle(Adaptor2d_HCurve2d) *R2,
-// int *NR1,
-// int *NR2,
-// Standard_Integer nbR1,
-// Standard_Integer nbR2,
-// const IntPatch_Point& VTX)
-void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *,
+
+#ifdef DUMPOFIntPatch_Intersection
+
+void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
Handle(Adaptor2d_HCurve2d) *,
+ int *NR1,
int *,
- int *,
- Standard_Integer ,
+ Standard_Integer nbR1,
Standard_Integer ,
- const IntPatch_Point& )
+ const IntPatch_Point& VTX)
{
- /*
+
if(VTX.IsOnDomS1()) {
//-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
printf("\n R Pas trouvee (IntPatch)\n");
}
- */
}
+#endif
-
-//void IntPatch_Intersection::Dump(const Standard_Integer Mode,
-void IntPatch_Intersection::Dump(const Standard_Integer ,
- const Handle(Adaptor3d_HSurface)& S1,
- const Handle(Adaptor3d_TopolTool)& D1,
- const Handle(Adaptor3d_HSurface)& S2,
- const Handle(Adaptor3d_TopolTool)& D2) const
+void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
+ const Handle(Adaptor3d_HSurface)& /*S1*/,
+ const Handle(Adaptor3d_TopolTool)& /*D1*/,
+ const Handle(Adaptor3d_HSurface)& /*S2*/,
+ const Handle(Adaptor3d_TopolTool)& /*D2*/) const
{
-
+#ifdef DUMPOFIntPatch_Intersection
+ const int MAXR = 200;
//-- ----------------------------------------------------------------------
//-- construction de la liste des restrictions & vertex
//--
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++;
}
printf("\nDUMP_INT: ----empt:%2ud tgte:%2ud oppo:%2ud ---------------------------------",empt,tgte,empt);
- Standard_Integer i,j,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
+ Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0;
nbl=NbLines();
for(i=1;i<=nbl;i++) {
printf("\nDUMP_LC :vtx :%2d r:%2d :%2d :%2d",
nbvw,nbvr,nbva,nbvg);
+ printf("\n");
-
- printf("\n");
+#endif
}