]> OCCT Git - occt-copy.git/commitdiff
0029257: GeomPlate generates surface in unexpected place CR29257_1
authormsv <msv@opencascade.com>
Tue, 24 Oct 2017 12:01:49 +0000 (15:01 +0300)
committermsv <msv@opencascade.com>
Tue, 14 Nov 2017 06:47:09 +0000 (09:47 +0300)
Treatment of the parameter EnlargeCoeff in the constructor of GeomPlate_MakeApprox has been corrected. Now the bounds of the result surface are correctly enlarged.

The new draw command 'pullupface' has been implemented to check behavior of GeomPlate.

The test case "perf modalg bug453_2" has been corrected. Now the area is computed the same on both Linux and Windows.

src/BRepTest/BRepTest_FillingCommands.cxx
src/GeomPlate/GeomPlate_MakeApprox.cxx
tests/bugs/modalg_7/bug29257_1 [new file with mode: 0644]
tests/bugs/modalg_7/bug29257_2 [new file with mode: 0644]
tests/perf/modalg/bug453_2

index 7bead0b63e843600c35d4f1b4401cb74f182176a..74bc9d58362ccc5be335980de6aa4c0e1e7e842c 100644 (file)
@@ -42,6 +42,8 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Curve.hxx>  
+#include <BRepExtrema_DistShapeShape.hxx>
+#include <BRepTools.hxx>
 #include <BRepTest.hxx>
 #include <DBRep.hxx>
 #include <Adaptor3d_HCurveOnSurface.hxx>
 #include <GeomPlate_PointConstraint.hxx>
 #include <GeomAdaptor_HSurface.hxx>
 #include <Geom_Surface.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GCPnts_QuasiUniformAbscissa.hxx>
 
 #include <TopoDS_Wire.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRepBuilderAPI_WireError.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
 #include <TColGeom2d_HArray1OfCurve.hxx>
 
 #include <AdvApp2Var_ApproxAFunc2Var.hxx>
@@ -92,6 +97,7 @@
 #include <Extrema_ExtPS.hxx>
 #include <Extrema_POnSurf.hxx>
 #include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
 #include <BRepOffsetAPI_MakeFilling.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Geom2d_TrimmedCurve.hxx>
@@ -694,7 +700,311 @@ static Standard_Integer fillingparam( Draw_Interpretor & di, Standard_Integer n,
 }
 
 
+//=======================================================================
+//function : addPointsOnCurveOnSurfaceConstraints
+//purpose  : 
+//=======================================================================
+static void addPointsOnCurveOnSurfaceConstraints(GeomPlate_BuildPlateSurface& thePlate,
+  const TopoDS_Edge &theEdge,
+  const TopoDS_Face &theFace,
+  const TopoDS_Shape& theAvoidEdges,
+  const Standard_Real theAvoidRadius,
+  const Standard_Real theStep,
+  const Standard_Real theTol3d,
+  const Standard_Real theTolAng,
+  const Standard_Integer theOrder,
+  TopoDS_Compound& thePoints)
+{
+  BRepAdaptor_Curve2d anAC2d(theEdge, theFace);
+  BRepAdaptor_Curve anAC(theEdge, theFace);
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
+
+  // discretize the curve
+  Standard_Real aLen = GCPnts_AbscissaPoint::Length(anAC);
+  Standard_Integer npt = Max(2, (Standard_Integer)(aLen / theStep));
+  GCPnts_QuasiUniformAbscissa aDiscr(anAC, npt);
+  if (!aDiscr.IsDone())
+    Standard_Failure::Raise("Failure discretization of an edge");
+
+  // do not take last point to avoid confusion with first point of the next edge
+  Standard_Integer aBegin = 1, anEnd = aDiscr.NbPoints();
+  if (theEdge.Orientation() == TopAbs_FORWARD)
+    anEnd--;
+  else
+    aBegin++;
+  for (Standard_Integer i = aBegin; i <= anEnd; i++)
+  {
+    Standard_Real aCPar = aDiscr.Parameter(i);
+    gp_Pnt2d aP2d = anAC2d.Value(aCPar);
+
+    // evaluate distance to avoid vertices
+    gp_Pnt aPnt = aSurf->Value(aP2d.X(), aP2d.Y());
+    TopoDS_Vertex aVert = BRepBuilderAPI_MakeVertex(aPnt);
+    Standard_Real aDist = RealLast();
+    if (!theAvoidEdges.IsNull())
+    {
+      BRepExtrema_DistShapeShape aDistSS(theAvoidEdges, aVert);
+      if (!aDistSS.IsDone())
+        Standard_Failure::Raise("Failure computation of distance between edges and vertex");
+      aDist = aDistSS.Value();
+    }
+    if (aDist > theAvoidRadius)
+    {
+      if (theOrder > 0)
+        thePlate.Add(new GeomPlate_PointConstraint
+                     (aP2d.X(), aP2d.Y(), aSurf, theOrder, theTol3d, theTolAng));
+      else
+        thePlate.Add(new GeomPlate_PointConstraint(aPnt, 0, theTol3d));
+      BRep_Builder().Add(thePoints, aVert);
+    }
+  }
+}
+
+//=======================================================================
+//function : addPointsOnCurveOnSurfaceConstraints
+//purpose  : 
+//=======================================================================
+static void addPointsOnSurfaceConstraints(GeomPlate_BuildPlateSurface& thePlate,
+  const TopoDS_Face& theFace,
+  const TopoDS_Shape& theAvoidEdges,
+  const Standard_Real theAvoidRadius,
+  const Standard_Real theStep,
+  const Standard_Real theTol3d,
+  TopoDS_Compound& thePoints)
+{
+  // make adapted surface with UV bounds
+  BRepAdaptor_Surface anASurf(theFace, Standard_True);
+  Standard_Real aU1 = anASurf.FirstUParameter();
+  Standard_Real aU2 = anASurf.LastUParameter();
+  Standard_Real aV1 = anASurf.FirstVParameter();
+  Standard_Real aV2 = anASurf.LastVParameter();
+
+  // get middle iso lines
+  Standard_Real aMidU = (aU1 + aU2) * 0.5;
+  Standard_Real aMidV = (aV1 + aV2) * 0.5;
+  Handle(Geom_Curve) aUIso = anASurf.Surface().Surface()->UIso(aMidU);
+  Handle(Geom_Curve) aVIso = anASurf.Surface().Surface()->VIso(aMidV);
+
+  // compute their length to decide which one to discretize
+  Standard_Real aUIsoLen = GCPnts_AbscissaPoint::Length(GeomAdaptor_Curve(aUIso, aV1, aV2));
+  Standard_Real aVIsoLen = GCPnts_AbscissaPoint::Length(GeomAdaptor_Curve(aVIso, aU1, aU2));
+  Standard_Boolean isUDiscr = aUIsoLen > aVIsoLen;
+
+  // discretize the longest iso line
+  Standard_Real aLongPar1 = aV1, aLongPar2 = aV2, anOrtPar1 = aU1, anOrtPar2 = aU2;
+  if (!isUDiscr)
+  {
+    aLongPar1 = aU1;
+    aLongPar2 = aU2;
+    anOrtPar1 = aV1;
+    anOrtPar2 = aV2;
+  }
+  GeomAdaptor_Curve anACLongIso(isUDiscr ? aUIso : aVIso);
+  Standard_Real aLongLen = (isUDiscr ? aUIsoLen : aVIsoLen);
+  Standard_Integer aLongNpt = Max(3, (Standard_Integer)(aLongLen / theStep));
+  GCPnts_QuasiUniformAbscissa aDiscr(anACLongIso, aLongNpt, aLongPar1, aLongPar2);
+  if (!aDiscr.IsDone())
+    Standard_Failure::Raise("Failure discretization of an iso line");
+
+  // do not take first and last points to avoid confusion with boundary
+  for (Standard_Integer i = 2; i <= aDiscr.NbPoints() - 1; i++)
+  {
+    Standard_Real anIsoPar = aDiscr.Parameter(i);
+    // get orthogonal iso line at this parameter
+    Handle(Geom_Curve) anOrtIso = (isUDiscr ? anASurf.Surface().Surface()->VIso(anIsoPar)
+      : anASurf.Surface().Surface()->UIso(anIsoPar));
+    // discretize the ort iso line
+    GeomAdaptor_Curve anACOrtIso(anOrtIso, anOrtPar1, anOrtPar2);
+    Standard_Real anOrtLen = GCPnts_AbscissaPoint::Length(anACOrtIso);
+    Standard_Integer anOrtNpt = Max(3, (Standard_Integer)(anOrtLen / theStep));
+    GCPnts_QuasiUniformAbscissa aDiscrOrt(anACOrtIso, anOrtNpt);
+    if (!aDiscrOrt.IsDone())
+      Standard_Failure::Raise("Failure discretization of an iso line");
+
+    // do not take first and last points to avoid confusion with boundary
+    for (Standard_Integer j = 2; j <= aDiscrOrt.NbPoints() - 1; j++)
+    {
+      Standard_Real anOrtPar = aDiscrOrt.Parameter(j);
+      gp_Pnt aPnt = anACOrtIso.Value(anOrtPar);
+
+      // evaluate distance between the point and avoid edges
+      TopoDS_Vertex aVert = BRepBuilderAPI_MakeVertex(aPnt);
+      BRepExtrema_DistShapeShape aDistSS(theAvoidEdges, aVert);
+      if (!aDistSS.IsDone())
+        Standard_Failure::Raise("Failure computation of distance between edges and vertex");
+      Standard_Real aDist = aDistSS.Value();
+      if (aDist > theAvoidRadius)
+      {
+        thePlate.Add(new GeomPlate_PointConstraint(aPnt, 0, theTol3d));
+        BRep_Builder().Add(thePoints, aVert);
+      }
+    }
+  }
+}
+
+//=======================================================================
+//function : pullupface
+//purpose  : 
+//=======================================================================
+static Standard_Integer pullupface(Draw_Interpretor& theDI,
+                                   Standard_Integer theArgc,
+                                   const char** theArgv)
+{
+  if (theArgc < 6)
+  {
+    cout << "incorrect usage, see help" << endl;
+    return 1;
+  }
 
+  TopoDS_Face aFace = TopoDS::Face(DBRep::Get(theArgv[2], TopAbs_FACE));
+  if (aFace.IsNull())
+  {
+    cout << "no such face " << theArgv[2] << endl;
+    return 1;
+  }
+  TopoDS_Shape anOldEdges = DBRep::Get(theArgv[3]);
+  if (anOldEdges.IsNull())
+  {
+    cout << "no such shape " << theArgv[3] << endl;
+    return 1;
+  }
+  TopoDS_Shape aNewEdges = DBRep::Get(theArgv[4]);
+  if (aNewEdges.IsNull())
+  {
+    cout << "no such shape " << theArgv[4] << endl;
+    return 1;
+  }
+  TopoDS_Face anOtherFace = TopoDS::Face(DBRep::Get(theArgv[5], TopAbs_FACE));
+  if (anOtherFace.IsNull())
+  {
+    cout << "no such face " << theArgv[5] << endl;
+    return 1;
+  }
+
+  Standard_Real aModifRadius = 0.1;
+  Standard_Integer anOrder = 1, aDegree = 3;
+  Standard_Real aTol2d = 0.00001, aTol3d = 0.0001, aTolAng = 0.01;
+  Standard_Real aStep = 0.1, anEnlargeCoeff = 1.01;
+  Standard_Integer anAppDegree = 8, anAppSegments = 9;
+  Standard_Boolean bAddInner = Standard_False, bAddBnd = Standard_False;
+  Standard_Boolean isOutputPnts = Standard_False;
+  for (Standard_Integer i = 6; i < theArgc; i++)
+  {
+    if (strcmp(theArgv[i], "-mr") == 0)
+      aModifRadius = Draw::Atof(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-order") == 0)
+      anOrder = Draw::Atoi(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-deg") == 0)
+      aDegree = Draw::Atoi(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-step") == 0)
+      aStep = Draw::Atof(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-tol2d") == 0)
+      aTol2d = Draw::Atof(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-tol3d") == 0)
+      aTol3d = Draw::Atof(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-tolang") == 0)
+      aTolAng = Draw::Atof(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-appdeg") == 0)
+      anAppDegree = Draw::Atoi(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-appsegs") == 0)
+      anAppSegments = Draw::Atoi(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-enlarge") == 0)
+      anEnlargeCoeff = Draw::Atof(theArgv[++i]);
+    else if (strcmp(theArgv[i], "-inner") == 0)
+      bAddInner = Standard_True;
+    else if (strcmp(theArgv[i], "-bnd") == 0)
+      bAddBnd = Standard_True;
+    else if (strcmp(theArgv[i], "-pnts") == 0)
+      isOutputPnts = Standard_True;
+    else
+    {
+      cout << "invalid option " << theArgv[i] << endl;
+      return 1;
+    }
+  }
+
+  // Init plate builder
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+  Standard_Real aU1, aU2, aV1, aV2;
+  BRepTools::UVBounds(aFace, aU1, aU2, aV1, aV2);
+  aSurf = new Geom_RectangularTrimmedSurface(aSurf, aU1, aU2, aV1, aV2);
+  Standard_Integer aNbIter = 1, aNbPtsOnCur = 10;
+  GeomPlate_BuildPlateSurface aPlate(aDegree, aNbPtsOnCur, aNbIter, aTol2d, aTol3d, aTolAng);
+  aPlate.LoadInitSurface(aSurf);
+
+  TopTools_IndexedMapOfShape anOldEMap;
+  TopExp::MapShapes(anOldEdges, TopAbs_EDGE, anOldEMap);
+
+  TopoDS_Compound aPoints;
+  BRep_Builder().MakeCompound(aPoints);
+
+  if (bAddBnd)
+  {
+    // Add face boundary constraints
+    for (TopExp_Explorer ex(aFace, TopAbs_EDGE); ex.More(); ex.Next())
+    {
+      TopoDS_Edge aE = TopoDS::Edge(ex.Current());
+      if (anOldEMap.Contains(aE))
+      {
+        // edge to be replaced, skip it
+        continue;
+      }
+      TopoDS_Vertex aV1, aV2;
+      TopExp::Vertices(aE, aV1, aV2);
+      addPointsOnCurveOnSurfaceConstraints(aPlate, aE, aFace, anOldEdges, aModifRadius,
+        aStep, aTol3d, aTolAng, anOrder, aPoints);
+    }
+  }
+
+  // add constraints of the replaced edges
+  for (TopExp_Explorer ex(aNewEdges, TopAbs_EDGE); ex.More(); ex.Next())
+  {
+    TopoDS_Edge aE = TopoDS::Edge(ex.Current());
+    //addPointsOnCurveConstraints(aPlate, aE, aStep, aTol3d, aPoints);
+    addPointsOnCurveOnSurfaceConstraints(aPlate, aE, anOtherFace, TopoDS_Shape(), 0.,
+      aStep, aTol3d, aTolAng, anOrder, aPoints);
+  }
+
+  if (bAddInner)
+  {
+    // add face inner constraints
+    addPointsOnSurfaceConstraints(aPlate, aFace, anOldEdges, aModifRadius, aStep, aTol3d, aPoints);
+  }
+
+  if (isOutputPnts)
+  {
+    DBRep::Set("pnts", aPoints);
+    theDI << "compound pnts is drawn\n";
+  }
+
+  // perform plate
+  aPlate.Perform();
+  if (!aPlate.IsDone())
+  {
+    theDI << "plate is not done";
+    return 0;
+  }
+
+  // build plate surface
+  Handle(GeomPlate_Surface) aPlateSurf = aPlate.Surface();
+  Standard_Real aDMax = Max(aTol3d, 10. * aPlate.G0Error());
+  TColgp_SequenceOfXY aS2d;
+  TColgp_SequenceOfXYZ aS3d;
+  aPlate.Disc2dContour(4, aS2d);
+  aPlate.Disc3dContour(4, 0, aS3d);
+  GeomPlate_PlateG0Criterion aCriterion(aS2d, aS3d, aDMax);
+  GeomPlate_MakeApprox anApprox(aPlateSurf, aCriterion, aTol3d,
+                                anAppSegments, anAppDegree, GeomAbs_C1, anEnlargeCoeff);
+  Handle(Geom_BSplineSurface) aNewSurf = anApprox.Surface();
+
+  // make new face
+  BRepBuilderAPI_MakeFace aFMaker(aNewSurf, Precision::Confusion());
+  TopoDS_Face aNewFace = aFMaker.Face();
+
+  DBRep::Set(theArgv[1], aNewFace);
+  theDI << "Done";
+  return 0;
+}
 
 void  BRepTest::FillingCommands(Draw_Interpretor& theCommands)
 {
@@ -738,4 +1048,21 @@ void  BRepTest::FillingCommands(Draw_Interpretor& theCommands)
                  fillingparam,
                  g) ;
 
+  theCommands.Add("pullupface",
+                  "result face old_edges new_edges modif_face [options]\n"
+                  "\t\tPull up the surface to new replacement edges. Options:\n"
+                  "\t\t-mr val      Modification radius [default 0.1]\n"
+                  "\t\t-bnd         Use face boundary constraints\n"
+                  "\t\t-inner       Use face inner points constraints\n"
+                  "\t\t-step val    Step of discretization [0.1]\n"
+                  "\t\t-order val   Order of continuity of point constraints (0/1) [1]\n"
+                  "\t\t-deg val     Degree of resolution for Plate (>=2) [3]\n"
+                  "\t\t-pnts        Output point constraints in the compound of vertices pnts\n"
+                  "\t\t-tol2d val   Tolerance to compare points in space of initial surface [1e-5]\n"
+                  "\t\t-tol3d val   Tolerance to compare points in 3d space [1e-4]\n"
+                  "\t\t-tolang val  Tolerance to compare normals of two points [1e-2]\n"
+                  "\t\t-appdeg val  Maximal degree for approximation of the surface [8]\n"
+                  "\t\t-appsegs val Maximal number of bezier pieces in output surface [9]"
+                  "\t\t-enlarge val Enlarge coefficient to extend boundaries of result surface [1.01]",
+                  __FILE__, pullupface, g);
 }
index dc53d80cf44ea23bc7b2bb71ff8b05f5c0f0e695..feafc67a977c42b7727db7e7ad47114dca11b99f 100644 (file)
@@ -257,10 +257,12 @@ GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& Surf
 
   Standard_Real U0=0., U1=0., V0=0., V1=0.;
   myPlate->RealBounds(U0, U1, V0, V1);
-  U0 = EnlargeCoeff * U0;
-  U1 = EnlargeCoeff * U1;
-  V0 = EnlargeCoeff * V0;
-  V1 = EnlargeCoeff * V1;
+  Standard_Real aDU = (U1 - U0) * (EnlargeCoeff - 1) * 0.5;
+  Standard_Real aDV = (V1 - V0) * (EnlargeCoeff - 1) * 0.5;
+  U0 = U0 - aDU;
+  U1 = U1 + aDU;
+  V0 = V0 - aDV;
+  V1 = V1 + aDV;
 
   Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1;
   Handle(TColStd_HArray1OfReal) nul1 =
@@ -351,10 +353,12 @@ GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& Surf
 
   Standard_Real U0=0., U1=0., V0=0., V1=0.;
   myPlate->RealBounds(U0, U1, V0, V1);
-  U0 = EnlargeCoeff * U0;
-  U1 = EnlargeCoeff * U1;
-  V0 = EnlargeCoeff * V0;
-  V1 = EnlargeCoeff * V1;
+  Standard_Real aDU = (U1 - U0) * (EnlargeCoeff - 1) * 0.5;
+  Standard_Real aDV = (V1 - V0) * (EnlargeCoeff - 1) * 0.5;
+  U0 = U0 - aDU;
+  U1 = U1 + aDU;
+  V0 = V0 - aDV;
+  V1 = V1 + aDV;
 
   Standard_Real seuil = Tol3d;
   if (CritOrder==0&&Tol3d<10*dmax) {
diff --git a/tests/bugs/modalg_7/bug29257_1 b/tests/bugs/modalg_7/bug29257_1
new file mode 100644 (file)
index 0000000..272d415
--- /dev/null
@@ -0,0 +1,61 @@
+puts "========"
+puts "OCC29257"
+puts "========"
+puts ""
+#################################################
+# GeomPlate generates surface in unexpected place
+#################################################
+
+set MaxDist 0.05
+
+restore [locate_data_file bug29257_plate_26_307.brep] a
+explode a
+
+# numbers of edges in a_1 to be replaced
+set old_edges_num {3}
+
+# get modified surface from a_2
+mksurface su a_2
+
+# create compounds of old edges and their replacements new edges
+shape old_edges C
+shape new_edges C
+
+foreach i $old_edges_num {
+  # get old edge and its curve 3d
+  subshape a_1 e $i
+  mkcurve c a_1_$i
+
+  # project it on modified surface, result is curve 2d
+  project cp c su -t 1e-2
+
+  # create 3d curve of projection
+  approxcurveonsurf ca cp su
+
+  # make new edge with pcurve
+  mkedge e ca
+  addpcurve e cp a_2
+  
+  add a_1_$i old_edges
+  add e new_edges
+}
+don a_1 new_edges
+
+# compute plate surface
+pullupface r a_1 old_edges new_edges a_2 -bnd -order 1 -mr 0.4 -step 0.4 -deg 3 -enlarge 1.1
+
+checkprops r -s 286.683
+
+# check distance from vertices of the initial face to the new face
+foreach v [explode a_1 v] {
+  distmini d $v r
+  set dist [dval d_val]
+  if {$dist > $MaxDist} {
+    puts "Error: distance from vertex $v to the result is $dist, which is > $MaxDist"
+  }
+}
+
+smallview 
+don r a_1
+fit
+checkview -screenshot -2d -path ${imagedir}/${test_image}_1.png
diff --git a/tests/bugs/modalg_7/bug29257_2 b/tests/bugs/modalg_7/bug29257_2
new file mode 100644 (file)
index 0000000..63e2a3f
--- /dev/null
@@ -0,0 +1,61 @@
+puts "========"
+puts "OCC29257"
+puts "========"
+puts ""
+#################################################
+# GeomPlate generates surface in unexpected place
+#################################################
+
+set MaxDist 0.1
+
+restore [locate_data_file bug29257_plate_8_3.brep] a
+explode a
+
+# numbers of edges in a_1 to be replaced
+set old_edges_num {2}
+
+# get modified surface from a_2
+mksurface su a_2
+
+# create compounds of old edges and their replacements new edges
+shape old_edges C
+shape new_edges C
+
+foreach i $old_edges_num {
+  # get old edge and its curve 3d
+  subshape a_1 e $i
+  mkcurve c a_1_$i
+
+  # project it on modified surface, result is curve 2d
+  project cp c su -t 1e-2
+
+  # create 3d curve of projection
+  approxcurveonsurf ca cp su
+
+  # make new edge with pcurve
+  mkedge e ca
+  addpcurve e cp a_2
+  
+  add a_1_$i old_edges
+  add e new_edges
+}
+don a_1 new_edges
+
+# compute plate surface
+pullupface r a_1 old_edges new_edges a_2 -bnd -order 1 -mr 0.4 -step 0.2 -deg 3 -enlarge 1.1
+
+checkprops r -s 9.02637
+
+# check distance from vertices of the initial face to the new face
+foreach v [explode a_1 v] {
+  distmini d $v r
+  set dist [dval d_val]
+  if {$dist > $MaxDist} {
+    puts "Error: distance from vertex $v to the result is $dist, which is > $MaxDist"
+  }
+}
+
+smallview 
+don r a_1
+fit
+checkview -screenshot -2d -path ${imagedir}/${test_image}_1.png
index 226e29edc2f1814bd356f3392c36fe7412d1de88..98be9bf59975f18a5123d88cba3471a00837922c 100644 (file)
@@ -22,6 +22,6 @@ tcopy result_1 result
 
 dchrono h2 stop counter blend
 
-checkprops result -s 3.65777e+06 
+checkprops result -s 3.54895e+006
 checkshape result
 checkview -display result -2d -path ${imagedir}/${test_image}.png