Compare commits

...

4 Commits

Author SHA1 Message Date
Markus Reichart 8b79817989 findings: the local operation's reach beside bare B-spline nets (#2978)
The cause, the bound and its Ruled extension model, the sketch of a
normal section (VectorCraft source beside it), and the seven cases of
topology.brep_local_operation that build now, each before (refused, the
input kept) and after, drawn by solidcore-diag from the same view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:33:15 -05:00
Markus Reichart c8c8df8649 goldens: bless topology.brep_local_operation, seven cases built beside nets (#2978)
Seven cases that the reach refused (ReachUncertified, status 1001, the
input put back as it came in) are built now, each a manifold solid that
passed the local operation's gate; nothing else moves in any unit.

  case     file                 was        now (volume)
  gen0000  Solids/extrusion.smb refused    647.1111714853831
  gen0021  Solids/extrusion.smb refused    687.0724147222363
  gen0031  Solids/extrusion.smb refused    500.08548890558274
  gen0041  Solids/extrusion.smb refused    580.9394352608608
  gen0048  Solids/extrusion.smb refused    623.0293856814408
  gen0059  Solids/extrusion.smb refused    462.59544953870954
  gen0076  Solids/pyramid.smb   refused    945813.736759979

Why they are right: gen0000, gen0021 and gen0048 (walls given planes) are
the prisms of their caps, ten times the bottom cap's area; gen0041 (the top
tilted) is the cap's area times the plane's height over its centroid;
gen0076 (the base moved up 1.31) is the similar pyramid above it,
V0 ((h - d)/h)^3: all within 1e-5 (tests/issue_2978_local_reach_beside_nets.rs).
gen0031 and gen0059 tilt a wall out of the vertical, so no prism formula
holds; they are manifold, pass the gate's check against the input, and are
drawn in the pull request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:33:15 -05:00
Markus Reichart d4ac008690 reach: a plane beside a bare B-spline net has a certified reach (#2978)
local_extension_reach bounded a plane against a labelled plane, cylinder,
cone or sphere, and against a kept B-spline face only along its
isocurves (SplineFace), so a local operation beside an extrusion with no
label, a moved net, or a corner of a plane with a quadric and a net or
with two nets was refused as ReachUncertified: on Solids/extrusion.smb
(main before the local operation built gen0000, gen0021, gen0041, gen0048
of topology.brep_local_operation) and on Solids/pyramid.smb, whose four
sides are bare B-spline nets.

- A B-spline surface or extrusion with no label and no definition is a
  bare net (reach/net.rs), a plane stored as a NURBS among them.
- A plane beside a net: in each normal section of the edge the plane's
  trace x0 + tau u meets the net at a (u, v, tau) proved by Krawczyk's
  operator for every section of a piece of the edge's parameters; the
  reach is sqrt(|x0 - p|^2 + tau^2), and the pieces are halved as for a
  quadric. Past a side the net is the extension the executive builds
  (Ruled: H + s' H_v homogeneous, one reparameterisation for every row;
  past a corner H + s' H_u + t' H_v + s' t' H_uv where both sides' rows end
  in one weight ratio). A closed direction runs on round its seam.
- Corners: two planes' line meets a net; where a boundary row of the net
  lies on one of the planes, the row meets the other plane (1 x 1); a
  plane, a quadric and a net (2 x 2); a plane and two nets (4 x 4). A
  moved net's move is bounded by the meetings on it.
- Where no meeting is proved (a plane moved off a round kept as its net)
  the reach is still ReachUncertified; so is a net past a side whose rows
  end in different weight ratios (past the rows' reach the extension takes
  the product form or is left short), and a net with unclamped ends or an
  inner knot of full multiplicity. A row within the B-rep's tolerance of a
  plane is taken as on it, as two planes within it are one.
- The isocurve bound (SplineFace, spline_face(_of), spline_reach(_along),
  spline_corner, SPLINE_STRIPS, SPLINE_REACH_TRIES, Exact::Spline) is
  replaced by the net's, as jyviko decided on #2978: one construction for
  every net, kept or moved, at edges and corners.

Tests: the round kept as its net is reached sqrt(2 r d) = 1 as on its
cylinder (was: refused, now the case for a plane moved off it), and its
tangent edge alone is bounded by sqrt(0.1^2 + 0.99) = 1; the tilted end
face beside the round's net reaches 0.45 at the round, also at the corner
where the side holds the net's boundary row (the bound now within the
B-rep's tolerance), and the net alone along its rulings 0.45 (the
isocurve test, on the net); the Ruled extension model in reach/net.rs is
checked against the extension extended_sides_keeping_parameters builds,
past each side and corner; the creased roof on the defective cube now
reaches the gate, which refuses it as Unsound with the input kept;
closed-form unit tests of the net's meetings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:33:15 -05:00
Markus Reichart 70f226ef0e test: planes moved beside bare B-spline nets build sound bodies (#2978)
The goldens cases gen0000, gen0021, gen0041 and gen0048 of
topology.brep_local_operation on Solids/extrusion.smb, two of whose walls
are extrusions with no analytic label (of a cubic B-spline, and of a
rational curve of lines and an arc): walls given their tangent planes, and
the top tilted, build prisms of the volume their caps give (ten times the
bottom cap's area; the cap's area times the tilted plane's height over its
centroid). And gen0076 on Solids/pyramid.smb, the base moved up beside
sides stored as bare nets: the similar pyramid above it, the volume times
((h - d) / h)^3. On local-operations they are refused as ReachUncertified.

And the five cases of #3042 on Solids/nurb_fillet.smb (face0_same,
face4_same, their attributed twins, fc0004): a sound manifold solid, or
refused with the input as it came in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-08 16:33:15 -05:00
16 changed files with 5889 additions and 497 deletions
@@ -60,7 +60,7 @@
{"case":"fc0029","deferred":null,"error":null,"ints":{"graph":{"blocks":[[5530,1048087],[2353,345210],[3761,443563],[8649,1231166],[11139,1119692],[2807,380758],[9671,1671146],[11579,901800],[9952,1471130],[17163,2342567],[25869,3493282],[20544,2673297]],"n":3058}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[1081.0,1081.0,34592.0]],"n":47},"geometry":{"blocks":[[2.5599999999999832e+22,2.5599999999999832e+22,3.2896e+24],[1.1999999999999975e+22,1.1999999999999975e+22,7.260000000000001e+23],[730.9442733577434,858.0120734429167,64858.61790680906]],"n":741},"record":{"blocks":[[155544.66853515652,155579.92476181663,19058058.264398053],[154883.12568554367,154941.51880574072,20324220.57230179],[142520.7082231047,142596.41784981615,18212653.135235615],[154806.4561564725,154972.45735892767,19093646.369808033],[155252.40131436303,155354.1721140812,20406811.642981462],[140642.9719392665,140862.60866179518,17894260.4774287],[154878.0705418264,155054.22088204307,19128506.313185643],[141068.82604785042,141433.55588031362,17527611.500434674],[154195.75,154556.75,18712557.75],[154243.50602216198,154538.41890063672,19941564.44806239],[140215.5,140487.5,17565873.5],[154703.36469041018,154878.00912893322,18777456.488563403],[155390.14231139628,155692.55151878114,20250848.848574623],[90721.45120858589,90868.34903995402,12471432.217107799],[90039.03768967514,90765.50307723251,11466839.444810867],[90449.58048159658,90968.38407563255,10645319.095995698],[15006.304828672948,15071.278910385701,75017.01759442406]],"n":4141},"surface_owners":{"blocks":[[20.0,20.0,210.0]],"n":20},"uv_curve_owners":{"blocks":[[4138.0,4332.0,257084.0]],"n":188}}}
{"case":"fc0030","deferred":null,"error":null,"ints":{"graph":{"blocks":[[5530,1048087],[2353,345210],[3761,443563],[8649,1231166],[11139,1119692],[2807,380758],[9671,1671146],[11579,901800],[9952,1471130],[17163,2342567],[25869,3493282],[20544,2673297]],"n":3058}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[1081.0,1081.0,34592.0]],"n":47},"geometry":{"blocks":[[2.5599999999999832e+22,2.5599999999999832e+22,3.2896e+24],[1.1999999999999975e+22,1.1999999999999975e+22,7.260000000000001e+23],[730.9442733577434,858.0120734429167,64858.61790680906]],"n":741},"record":{"blocks":[[155544.66853515652,155579.92476181663,19058058.264398053],[154883.12568554367,154941.51880574072,20324220.57230179],[142520.7082231047,142596.41784981615,18212653.135235615],[154806.4561564725,154972.45735892767,19093646.369808033],[155252.40131436303,155354.1721140812,20406811.642981462],[140642.9719392665,140862.60866179518,17894260.4774287],[154878.0705418264,155054.22088204307,19128506.313185643],[141068.82604785042,141433.55588031362,17527611.500434674],[154195.75,154556.75,18712557.75],[154243.50602216198,154538.41890063672,19941564.44806239],[140215.5,140487.5,17565873.5],[154703.36469041018,154878.00912893322,18777456.488563403],[155390.14231139628,155692.55151878114,20250848.848574623],[90721.45120858589,90868.34903995402,12471432.217107799],[90039.03768967514,90765.50307723251,11466839.444810867],[90449.58048159658,90968.38407563255,10645319.095995698],[15006.304828672948,15071.278910385701,75017.01759442406]],"n":4141},"surface_owners":{"blocks":[[20.0,20.0,210.0]],"n":20},"uv_curve_owners":{"blocks":[[4138.0,4332.0,257084.0]],"n":188}}}
{"case":"fc0031","deferred":null,"error":null,"ints":{"graph":{"blocks":[[175,12385]],"n":121}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[1.2e+21,1.2e+21,7.8e+21]],"n":31},"record":{"blocks":[[86448.35010058085,86489.35010058085,5479421.844715244]],"n":164},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,2.0,-1.0,-1.0,-1.0]}}
{"case":"gen0000","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0000","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2508,322157],[2737,381059],[5730,644350],[3544,630392],[6005,593789],[9923,1440534],[12774,1466844]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[666.3426207657327,9877518.473090675,9934452.135103568]],"n":424},"record":{"blocks":[[140974.2238529436,141052.06708209866,18166303.110872176],[127326.48126003167,127483.81247437863,17674464.920045],[128058.53158445854,128242.78759522102,17395060.81315641],[91081.30411119803,45482006.46488623,-5192257.522908466],[60762.71681469282,60811.28318530718,5140971.371759845]],"n":1210},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-108.0,108.0,-5886.0]],"n":108}}}
{"case":"gen0001","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0002","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1881,231784],[3468,553413],[2259,207996],[5091,517645],[9023,1312991],[4471,251788]],"n":1396}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[210.0,210.0,3080.0]],"n":21},"geometry":{"blocks":[[1.6799999999999925e+22,1.6799999999999925e+22,1.4196e+24],[-69.63094524647565,356.3690547535241,-2111.0734133096885]],"n":337},"record":{"blocks":[[140553.5,140965.5,18120762.0],[126937.62293491785,127069.62293491785,17636628.660356514],[103742.12293491785,104116.12293491785,13264092.515550645],[75988.12293491783,76084.12293491783,8443981.054912265]],"n":1001},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-84.0,84.0,-3570.0]],"n":84}}}
{"case":"gen0003","deferred":null,"error":null,"ints":{"graph":{"blocks":[[692,106331],[25,79]],"n":261}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0],"geometry":{"blocks":[[2.4e+21,2.4000000000000084e+21,3.000000000000001e+22]],"n":56},"record":{"blocks":[[87521.25275474228,43841294.327081785,215143713.92267185]],"n":210},"surface_owners":[1.0,1.0,1.0],"uv_curve_owners":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
@@ -81,7 +81,7 @@
{"case":"gen0018","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1485,181651],[2387,261025],[3175,417519],[6648,902856]],"n":1019}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0],"geometry":{"blocks":[[1.1999999999999975e+22,1.1999999999999975e+22,7.260000000000001e+23]],"n":240},"record":{"blocks":[[157217.22447274308,157231.22447274308,19278198.216036484],[156157.13303146334,156419.82363523965,20447243.250780012],[141455.48021756337,141593.08071388188,17996368.187218934],[155107.52131219086,155348.7302645498,19149360.30337226],[104573.08452012748,104661.55858306825,11530544.626243796],[30393.128551147056,30431.024802910142,904071.2969962137]],"n":1370},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[405.0,465.0,7625.0]],"n":60}}}
{"case":"gen0019","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0020","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0021","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0021","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2508,322157],[2737,381059],[5730,644350],[3544,630392],[6005,593789],[9923,1440534],[12774,1466844]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[679.247730594307,9877527.828234844,9936130.320583055]],"n":424},"record":{"blocks":[[140963.82226276476,141045.3103206927,18166285.505433835],[127314.98823878425,127477.26331205857,17673788.0908405],[128034.57956527523,128233.61473746217,17393155.311088845],[91092.90486821948,45481951.13323095,-5188756.241267705],[60762.71681469282,60811.28318530718,5140971.371759845]],"n":1210},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-108.0,108.0,-5886.0]],"n":108}}}
{"case":"gen0022","deferred":null,"error":null,"ints":{"graph":{"blocks":[[50,1663]],"n":71}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":[1e+20,1e+20,1e+20,1e+20,5.551115123125783e-17,8.881784197001252e-16,-1.0229128535520042,0.00001,-1234567.0,-1234567.0,1234567.0,1234567.0,0.00001,-30.61467458920718,0.0,0.00001],"record":{"blocks":[[28982.89523240007,21960831.59885814,123206142.72427092]],"n":70},"surface_owners":[1.0],"uv_curve_owners":[-1.0,-1.0]}}
{"case":"gen0023","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0024","deferred":null,"error":null,"ints":{"graph":{"blocks":[[50,1663]],"n":71}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":[1e+20,1e+20,1e+20,1e+20,0.0,0.0,0.6729906661212666,0.00001,-1234567.0,-1234567.0,1234567.0,1234567.0,0.00001,-30.61467458920718,0.0,0.00001],"record":{"blocks":[[29004.807194736204,19782192.036543917,123949058.81897196]],"n":70},"surface_owners":[1.0],"uv_curve_owners":[-1.0,-1.0]}}
@@ -91,7 +91,7 @@
{"case":"gen0028","deferred":null,"error":null,"ints":{"graph":{"blocks":[[682,105286],[29,96]],"n":261}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0],"geometry":{"blocks":[[2.4e+21,2.4e+21,2.9999999999999996e+22]],"n":56},"record":{"blocks":[[142982.44946801648,143164.44946801648,15937837.083377652],[30107.0,30287.0,771201.0]],"n":342},"surface_owners":[1.0,1.0,1.0],"uv_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
{"case":"gen0029","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0030","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1296,157069],[2328,235553],[3587,458155],[6012,680472]],"n":985}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0],"geometry":{"blocks":[[1.1999999999999975e+22,1.1999999999999975e+22,7.260000000000001e+23]],"n":240},"record":{"blocks":[[155889.5,155901.5,19084516.0],[154524.26679056452,154754.26679056452,20294414.16484167],[140727.0,140747.0,17917951.0],[154823.9825193369,154889.9825193369,19101055.99218987],[103941.5,103945.5,11452164.0],[30322.62862549696,30351.572897406964,900460.083544985]],"n":1370},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[405.0,465.0,7625.0]],"n":60}}}
{"case":"gen0031","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0031","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2508,322157],[2737,381059],[5730,644350],[3544,630392],[6005,593789],[9923,1440534],[12774,1466844]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[615.8846177461531,14815740.328712061,14867121.579591237]],"n":424},"record":{"blocks":[[140987.2736643996,141060.86746726738,18167363.483604513],[127271.2210827841,127432.17815770011,17660390.497585837],[128002.63741952149,128193.04443412332,17391234.07712418],[91053.96848240259,65856740.31616496,77823261.30486597],[60762.71681469282,60811.28318530718,5140971.371759845]],"n":1210},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-108.0,108.0,-5886.0]],"n":108}}}
{"case":"gen0032","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0033","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1277,174490],[2444,346534],[4114,669278],[778,14800]],"n":804}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0],"geometry":{"blocks":[[9.6e+21,9.600000000000017e+21,4.6559999999999995e+23]],"n":194},"record":{"blocks":[[141253.1029586434,141336.67310083122,18233727.58146279],[910456.8947865181,29741318.114338845,368938141.54290855],[-791133.6058079528,13482279.819274934,-89893885.21058506]],"n":585},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-48.0,48.0,-1176.0]],"n":48}}}
{"case":"gen0034","deferred":null,"error":null,"ints":{"graph":{"blocks":[[682,105286],[29,96]],"n":261}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0],"geometry":{"blocks":[[2.4e+21,2.4e+21,2.9999999999999996e+22]],"n":56},"record":{"blocks":[[142982.44946801648,143164.44946801648,15937837.083377652],[30107.0,30287.0,771201.0]],"n":342},"surface_owners":[1.0,1.0,1.0],"uv_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
@@ -101,14 +101,14 @@
{"case":"gen0038","deferred":null,"error":null,"ints":{"graph":{"blocks":[[104,5428]],"n":99}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":24},"record":{"blocks":[[58410.52515099852,58471.59621881038,2310587.9923582436]],"n":116},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0039","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1277,174490],[2444,346534],[4114,669278],[778,14800]],"n":804}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0],"geometry":{"blocks":[[9.6e+21,9.600000000000017e+21,4.656000000000001e+23]],"n":194},"record":{"blocks":[[141125.56968884318,141205.72410907954,18211054.808841206],[856315.8199191247,28873797.151187282,281138581.99902],[-736999.2588899866,14771293.71724904,24109598.28267207]],"n":585},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-48.0,48.0,-1176.0]],"n":48}}}
{"case":"gen0040","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1172,159991],[1948,311927],[978,28202]],"n":573}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0],"geometry":{"blocks":[[6.4e+21,6.4e+21,2.0799999999999997e+23]],"n":133},"record":{"blocks":[[156360.52780532837,158006.30563557148,19068776.25026989],[153903.1388885975,156472.02783429623,20181493.582973957],[104892.00006401539,108480.00015670061,12407745.286694974],[258.6666741371155,509.33334589004517,2804.4445185661316]],"n":784},"surface_owners":[1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[360.0,392.0,9416.0]],"n":32}}}
{"case":"gen0041","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0041","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2508,322157],[2737,381059],[5730,644350],[3544,630392],[6005,593789],[9923,1440534],[12774,1466844]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[493.70576312502754,4938871.29528567,4974338.599395086]],"n":424},"record":{"blocks":[[140835.77099348552,140907.77099348552,18158499.333163507],[127378.02987628388,127450.02987628388,17689934.168712076],[128134.7764585532,128226.7764585532,17415186.995899804],[91087.80571986358,20675863.00152347,72070148.91494854],[60762.71681469282,60820.78556864008,5140969.303322095]],"n":1210},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-108.0,108.0,-5886.0]],"n":108}}}
{"case":"gen0042","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1277,174490],[2444,346534],[4114,669278],[778,14800]],"n":804}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0],"geometry":{"blocks":[[9.6e+21,9.600000000000008e+21,4.656000000000001e+23]],"n":194},"record":{"blocks":[[141028.51753995748,141100.51753995748,18209140.71170544],[104020.45910069923,20901260.41429212,82962163.56631431],[15281.0,15292.597876826972,503374.6497665959]],"n":585},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-48.0,48.0,-1176.0]],"n":48}}}
{"case":"gen0043","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1881,231784],[3468,553413],[2259,207996],[5091,517645],[9023,1312991],[4471,251788]],"n":1396}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[210.0,210.0,3080.0]],"n":21},"geometry":{"blocks":[[1.6799999999999925e+22,1.6799999999999933e+22,1.4196e+24],[97.07644014672621,273.0764401467262,4532.062022572823]],"n":337},"record":{"blocks":[[140827.5568614641,140999.5568614641,18163612.41307346],[127029.93663265301,127151.93663265301,17644141.082648907],[103806.82188705914,19857052.821887065,77472491.1227448],[75988.12293491783,76084.12293491783,8443981.054912265]],"n":1001},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-84.0,84.0,-3570.0]],"n":84}}}
{"case":"gen0044","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1172,159991],[1948,311927],[978,28202]],"n":573}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0],"geometry":{"blocks":[[6.4e+21,6.4e+21,2.0799999999999997e+23]],"n":133},"record":{"blocks":[[156360.52780532837,158006.30563557148,19068776.25026989],[153903.1388885975,156472.02783429623,20181493.582973957],[104892.00006401539,108480.00015670061,12407745.286694974],[258.6666741371155,509.33334589004517,2804.4445185661316]],"n":784},"surface_owners":[1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[360.0,392.0,9416.0]],"n":32}}}
{"case":"gen0045","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0046","deferred":null,"error":null,"ints":{"graph":{"blocks":[[104,5428]],"n":99}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":24},"record":{"blocks":[[58410.52515099852,58471.59621881038,2310587.9923582436]],"n":116},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0047","deferred":null,"error":null,"ints":{"graph":{"blocks":[[692,106331],[25,79]],"n":261}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0],"geometry":{"blocks":[[2.4e+21,2.4000000000000084e+21,3.000000000000001e+22]],"n":56},"record":{"blocks":[[87521.9169102232,40095667.79834579,194151991.58350927]],"n":210},"surface_owners":[1.0,1.0,1.0],"uv_curve_owners":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
{"case":"gen0048","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0048","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2508,322157],[2737,381059],[5730,644350],[3544,630392],[6005,593789],[9923,1440534],[12774,1466844]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[606.257544775902,4939172.362337735,4987194.028411555]],"n":424},"record":{"blocks":[[140935.6381299591,141013.4813591142,18164983.31700817],[127300.62823450065,127457.95944884761,17672849.589725796],[127966.47478588187,128150.73079664435,17388950.893938813],[91124.98240081035,22660748.32632806,-39751764.701571964],[60762.71681469282,60811.28318530718,5140971.371759845]],"n":1210},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-108.0,108.0,-5886.0]],"n":108}}}
{"case":"gen0049","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0050","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1485,181651],[2387,261025],[3175,417519],[6648,902856]],"n":1019}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0],"geometry":{"blocks":[[1.1999999999999975e+22,1.1999999999999975e+22,7.260000000000001e+23]],"n":240},"record":{"blocks":[[157217.22447274308,157231.22447274308,19278198.216036484],[156157.13303146334,156419.82363523965,20447243.250780012],[141455.48021756337,141593.08071388188,17996368.187218934],[155107.52131219086,155348.7302645498,19149360.30337226],[104573.08452012748,104661.55858306825,11530544.626243796],[30393.128551147056,30431.024802910142,904071.2969962137]],"n":1370},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[405.0,465.0,7625.0]],"n":60}}}
{"case":"gen0051","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1277,174490],[2444,346534],[4114,669278],[778,14800]],"n":804}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0],"geometry":{"blocks":[[9.6e+21,9.600000000000025e+21,4.6559999999999995e+23]],"n":194},"record":{"blocks":[[141092.90971071896,141221.69068258165,18207690.57520062],[104028.99814035674,65874074.66927339,338695340.2160862],[15280.999999999993,15402.906760956694,502964.8308552575]],"n":585},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-48.0,48.0,-1176.0]],"n":48}}}
@@ -119,7 +119,7 @@
{"case":"gen0056","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0057","deferred":null,"error":null,"ints":{"graph":{"blocks":[[692,106331],[25,79]],"n":261}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0],"geometry":{"blocks":[[2.4e+21,2.400000000000004e+21,3.0000000000000004e+22]],"n":56},"record":{"blocks":[[87495.35549293598,19840768.588122904,71346522.82882571]],"n":210},"surface_owners":[1.0,1.0,1.0],"uv_curve_owners":[-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
{"case":"gen0058","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1277,174490],[2444,346534],[4114,669278],[778,14800]],"n":804}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0],"geometry":{"blocks":[[9.6e+21,9.600000000000017e+21,4.6559999999999995e+23]],"n":194},"record":{"blocks":[[141186.52911685206,141258.52911685206,18221543.461588066],[-1515580.127978588,27179463.490194604,-332182873.19711703],[1634882.5731820147,14575708.153637713,36214671.04161818]],"n":585},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-48.0,48.0,-1176.0]],"n":48}}}
{"case":"gen0059","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2468,318735],[2755,382199],[5710,650567],[3534,632497],[6013,592519],[9779,1412900],[12928,1499698]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[431.5198428883937,624.652584117112,27447.906125791415]],"n":424},"record":{"blocks":[[156224.41673182778,156297.18329645565,19149526.127055034],[154598.40251211118,154985.87177838173,20301423.514221795],[140664.7203279845,140836.2024273099,17905887.2094762],[154920.03783534584,154938.03783534584,19116535.34318591],[154743.16176198598,154820.03053193798,20312026.989448104],[140446.0,140764.0,17885794.0],[154426.5,154613.5,19052446.0],[129684.24687969516,129844.4946593029,14955378.32523922],[91187.66304535375,91247.66304535375,11441009.498965224],[30370.71681469282,30387.28318530718,1022758.4248081051]],"n":2398},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[1377.0,1485.0,48069.0]],"n":108}}}
{"case":"gen0059","deferred":null,"error":null,"ints":{"graph":{"blocks":[[2508,322157],[2737,381059],[5730,644350],[3544,630392],[6005,593789],[9923,1440534],[12774,1466844]],"n":1777}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[351.0,351.0,6552.0]],"n":27},"geometry":{"blocks":[[2.1599999999999874e+22,2.1599999999999874e+22,2.3436e+24],[576.479912043791,9877403.191385778,9922263.828823194]],"n":424},"record":{"blocks":[[140960.93079587494,141032.93079587494,18166850.62474821],[127255.44270984929,127414.00046731443,17659903.3699522],[127999.14773026791,128178.73507590464,17389989.730407752],[91113.69032347939,43510619.86313032,96805260.33414717],[60762.71681469282,60811.28318530718,5140971.371759845]],"n":1210},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-108.0,108.0,-5886.0]],"n":108}}}
{"case":"gen0060","deferred":null,"error":null,"ints":{"graph":{"blocks":[[50,1663]],"n":71}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":[1e+20,1e+20,1e+20,1e+20,0.0,0.0,0.7261627726849257,0.00001,-1234567.0,-1234567.0,1234567.0,1234567.0,0.00001,-30.61467458920718,0.0,0.00001],"record":{"blocks":[[29005.551604228152,19782192.780953407,123949089.18024483]],"n":70},"surface_owners":[1.0],"uv_curve_owners":[-1.0,-1.0]}}
{"case":"gen0061","deferred":null,"error":null,"ints":{"graph":{"blocks":[[50,1663]],"n":71}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":[1e+20,1e+20,1e+20,1e+20,0.0,5.0,0.0,0.00001,-10.0,-5.0,0.0,4.999999999999999,0.00001,-30.61467458920718,0.0,0.00001],"record":{"blocks":[[29010.385325410793,29185.614674589207,492554.5413016432]],"n":70},"surface_owners":[1.0],"uv_curve_owners":[-1.0,-1.0]}}
{"case":"gen0062","deferred":null,"error":null,"ints":{"graph":{"blocks":[[682,105286],[29,96]],"n":261}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0],"geometry":{"blocks":[[2.4e+21,2.4e+21,2.9999999999999996e+22]],"n":56},"record":{"blocks":[[142982.44946801648,143164.44946801648,15937837.083377652],[30107.0,30287.0,771201.0]],"n":342},"surface_owners":[1.0,1.0,1.0],"uv_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0]}}
@@ -136,7 +136,7 @@
{"case":"gen0073","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0074","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1277,174490],[2444,346534],[4114,669278],[778,14800]],"n":804}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0],"geometry":{"blocks":[[9.6e+21,9.600000000000025e+21,4.6559999999999995e+23]],"n":194},"record":{"blocks":[[141078.67945932975,141262.36447332427,18213079.47648731],[-2365134.5339968833,49170000.150317684,-534069203.35257745],[2484425.6882363446,12360978.591230411,116552981.21678422]],"n":585},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-48.0,48.0,-1176.0]],"n":48}}}
{"case":"gen0075","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1172,159991],[1948,311927],[978,28202]],"n":573}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0],"geometry":{"blocks":[[6.4e+21,6.4e+21,2.0799999999999997e+23]],"n":133},"record":{"blocks":[[156360.52780532837,158006.30563557148,19068776.25026989],[153903.1388885975,156472.02783429623,20181493.582973957],[104892.00006401539,108480.00015670061,12407745.286694974],[258.6666741371155,509.33334589004517,2804.4445185661316]],"n":784},"surface_owners":[1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[360.0,392.0,9416.0]],"n":32}}}
{"case":"gen0076","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1172,159991],[1948,311927],[978,28202]],"n":573}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0],"geometry":{"blocks":[[6.4e+21,6.4e+21,2.0799999999999997e+23]],"n":133},"record":{"blocks":[[156360.52780532837,158006.30563557148,19068776.25026989],[153903.1388885975,156472.02783429623,20181493.582973957],[104892.00006401539,108480.00015670061,12407745.286694974],[258.6666741371155,509.33334589004517,2804.4445185661316]],"n":784},"surface_owners":[1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[360.0,392.0,9416.0]],"n":32}}}
{"case":"gen0076","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1191,161874],[1949,313933],[974,28428]],"n":573}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0],"geometry":{"blocks":[[6.4e+21,6.400000000000004e+21,2.0799999999999997e+23]],"n":133},"record":{"blocks":[[-3573955.801055106,13714426.230891941,-884935273.6169126],[3765521.6562693026,6237320.46813458,20670087.030879214]],"n":432},"surface_owners":[1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-32.0,32.0,-528.0]],"n":32}}}
{"case":"gen0077","deferred":null,"error":null,"ints":{"graph":{"blocks":[[50,1663]],"n":71}},"topology":null,"values":{"edge_curve_owners":[0.0],"geometry":[1e+20,1e+20,1e+20,1e+20,0.0,5.0,0.0,0.00001,-10.0,-5.0,0.0,4.999999999999999,0.00001,-30.61467458920718,0.0,0.00001],"record":{"blocks":[[29010.385325410793,29185.614674589207,492554.5413016432]],"n":70},"surface_owners":[1.0],"uv_curve_owners":[-1.0,-1.0]}}
{"case":"gen0078","deferred":null,"error":null,"ints":{"graph":{"blocks":[[101,5336]],"n":97}},"topology":null,"values":{"edge_curve_owners":[0.0,1.0],"geometry":{"blocks":[[8e+20,8e+20,3.6e+21]],"n":27},"record":{"blocks":[[72141.8827762868,72278.09763810274,3691636.3260077816]],"n":140},"surface_owners":[1.0],"uv_curve_owners":[0.0,1.0,-1.0,-1.0]}}
{"case":"gen0079","deferred":null,"error":null,"ints":{"graph":{"blocks":[[1881,231784],[3468,553413],[2259,207996],[5091,517645],[9023,1312991],[4471,251788]],"n":1396}},"topology":null,"values":{"edge_curve_owners":{"blocks":[[210.0,210.0,3080.0]],"n":21},"geometry":{"blocks":[[1.6799999999999925e+22,1.679999999999995e+22,1.4196e+24],[247.87446819416934,292.6310905949567,11255.605714095394]],"n":337},"record":{"blocks":[[140956.03803434453,141040.53803434453,18185296.49393398],[127239.77528722705,127311.77528722705,17668690.287975267],[-3599843.39161713,48252017.31114167,-789183361.4693285],[3779671.2271521315,11187235.78436824,114616369.86204277]],"n":1001},"surface_owners":[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0],"uv_curve_owners":{"blocks":[[-84.0,84.0,-3570.0]],"n":84}}}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2502,11 +2502,13 @@ mod tests {
}
/// The same cube, its top given a roof with a ridge: a degree-1 B-spline patch whose
/// interior knot is a crease. The roof has no exact class, so the reach of the moved
/// top has no certified bound: refused as `ReachUncertified` at the top, before any
/// body is built, the cube as it came in with the input's own failures.
/// interior knot is a crease. The roof is a bare net beside the sides, and the reach is
/// bounded where it meets them (across the crease too: the net is continuous there), so
/// a body is built; it fails more of the check than the cube did (the sides along the
/// ridge meet the roof in a kinked line), so the gate refuses it as `Unsound`, and the
/// cube is as it came in, with the input's own failures.
#[test]
fn a_creased_roof_on_a_defective_input_is_refused_as_reach_uncertified() {
fn a_creased_roof_on_a_defective_input_is_refused_as_unsound() {
use crate::nurbs::b_spline_surface::BSplineSurface;
use crate::nurbs::math::{CPoint, NOW};
use crate::nurbs::srf_basic::Surface as Net;
@@ -2527,7 +2529,15 @@ mod tests {
.unwrap();
let roof = Surface::from(BSplineSurface::from_gw_nurb(&roof));
let why = refused_unchanged_or_returned(&mut k, &mut b, &[top], vec![roof]);
assert_eq!(why, Some(OffsetFailure::ReachUncertified { face: top }));
assert!(
matches!(
why,
Some(OffsetFailure::Unsound {
what: crate::error::offset::Unsoundness::Check { .. }
})
),
"{why:?}"
);
assert_eq!(failure_classes(&mut k, &b), had);
}
@@ -0,0 +1,318 @@
//! The local operation's reach beside bare B-spline nets: planes moved beside the walls of
//! `Solids/extrusion.smb`, two of which are extrusions with no analytic label (of a cubic
//! B-spline and of a rational curve of lines and an arc; the reader makes its other faces
//! planes and cylinders), build sound bodies of their closed-form volumes instead of being
//! refused as `ReachUncertified`; so does the base of `Solids/pyramid.smb` moved up,
//! beside sides stored as bare B-spline nets; and
//! the planes moved over the curved nets of `Solids/nurb_fillet.smb` (the cases whose
//! extension can leave a body that is no manifold solid) are built sound or refused with
//! the input left as it came in, never returned unsound.
//!
//! Each case is a goldens case of `topology.brep_local_operation`, made as its runner makes
//! it: a face's surface replaced by the plane through the point at the middle of its UV
//! domain, moved `offset` along the surface's normal there, the normal tilted by `tilt`.
//!
//! The solids are the upstream test files, read when the pinned upstream checkout is
//! present (the tests are skipped otherwise, as in CI's test job).
#![allow(
clippy::unwrap_used,
clippy::expect_used,
clippy::panic,
clippy::indexing_slicing
)] // test helpers
#[path = "support/offset_fixture.rs"]
mod offset_fixture;
use offset_fixture::Notifications;
use solidcore::geom::attribute::{AttributeStore, ObjectKey};
use solidcore::geom::object::ObjectRef;
use solidcore::mass::integrator::properties::{face_area, face_centroid};
use solidcore::math::{Point3, Vec3};
use solidcore::nurbs::knots::Side;
use solidcore::surface::plane::Plane;
use solidcore::surface::surface::Surface;
use solidcore::topology::brep::local_operation::local_operation;
use solidcore::topology::brep::p1 as bp1;
use solidcore::topology::brep::p10::TopologyEnv;
use solidcore::topology::brep::p7::read_from_file;
use solidcore::topology::brep::validation::volume;
use solidcore::topology::database_io::FileType;
use solidcore::topology::face::p2 as face_ops;
use solidcore::topology::topology::NotifyRecords;
use solidcore::topology::FaceId;
use solidcore::{Brep, EntityRef, Kernel};
/// The upstream test file `Solids/<name>`, or `None` without the upstream checkout.
fn solid(k: &mut Kernel, name: &str) -> Option<Brep> {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../upstream/TestFiles/pt_TestFiles/Solids")
.join(name);
let Ok(bytes) = std::fs::read(&path) else {
assert!(
std::env::var_os("SOLIDCORE_REQUIRE_UPSTREAM").is_none(),
"SOLIDCORE_REQUIRE_UPSTREAM is set and the upstream test file is missing: {}",
path.display()
);
eprintln!("unavailable upstream test file: {}", path.display());
return None;
};
let mut b = Brep::new_with_infinite_region().unwrap();
let mut records = NotifyRecords::new();
let mut attributes = AttributeStore::default();
let key = |_: EntityRef| ObjectRef {
key: ObjectKey(0),
type_code: 0,
};
let mut env = TopologyEnv {
all_attributes: &[],
attributes: &mut attributes,
key_of: &key,
records: &mut records,
next_key: 1 << 50,
};
read_from_file(k, &mut b, bytes, FileType::Ascii, false, &mut env).unwrap();
b.use_arena_naming().unwrap();
Some(b)
}
/// The plane the goldens runner gives face `index` (`GetFaces` order): through the point
/// at the middle of its UV domain moved `offset` along the normal there, the normal plus
/// `tilt`: the face, and the plane's origin and normal.
fn plane_for(
k: &Kernel,
b: &Brep,
index: usize,
offset: f64,
tilt: [f64; 3],
) -> (FaceId, (Point3, Vec3)) {
let face = bp1::faces(b, None).unwrap()[index];
let surface = face_ops::surface(b, face).unwrap().unwrap();
let uv = b.face(face).unwrap().uv_domain.evaluate(0.5, 0.5);
let p = surface.evaluate_point(k, uv).unwrap();
let n = surface
.evaluate_normal(k, uv, Side::Left, Side::Left)
.unwrap();
let origin = Point3::new(p.x + n.x * offset, p.y + n.y * offset, p.z + n.z * offset);
let normal = Vec3::new(n.x + tilt[0], n.y + tilt[1], n.z + tilt[2]);
(face, (origin, normal))
}
/// `b`'s faces `moves` (index, offset, tilt) given their planes by a local operation; the
/// planes' origins and normals.
fn moved(
k: &mut Kernel,
b: &mut Brep,
moves: &[(usize, f64, [f64; 3])],
) -> solidcore::Result<Vec<(Point3, Vec3)>> {
let (faces, planes): (Vec<FaceId>, Vec<(Point3, Vec3)>) = moves
.iter()
.map(|&(i, offset, tilt)| plane_for(k, b, i, offset, tilt))
.unzip();
let surfaces = planes
.iter()
.map(|&(o, n)| Surface::from(Plane::from_normal(o, n)))
.collect();
let mut notifications = Notifications::new(b);
local_operation(k, b, &faces, surfaces, &mut notifications.context())?;
Ok(planes)
}
/// The face of `b` whose surface's point at the middle of its domain is at height `z`, and
/// whose normal there is along z (a cap of the extrusion).
fn cap_at(k: &Kernel, b: &Brep, z: f64) -> FaceId {
let caps: Vec<FaceId> = bp1::faces(b, None)
.unwrap()
.into_iter()
.filter(|&f| {
let s = face_ops::surface(b, f).unwrap().unwrap();
let uv = b.face(f).unwrap().uv_domain.evaluate(0.5, 0.5);
let p = s.evaluate_point(k, uv).unwrap();
let n = s.evaluate_normal(k, uv, Side::Left, Side::Left).unwrap();
(p.z - z).abs() < 1e-9 && n.x.abs() < 1e-9 && n.y.abs() < 1e-9
})
.collect();
assert_eq!(caps.len(), 1, "{caps:?}");
caps[0]
}
/// The integrators' accuracy, and the agreement asked of two integrals at it.
const ACCURACY: f64 = 1e-6;
const AGREE: f64 = 1e-5;
/// Walls of the extrusion (z from 0 to 10) moved onto planes, the caps kept: the result
/// is the prism over its bottom cap, ten times the cap's area, and sound, and each new wall
/// stands on its plane (at least four of the body's vertices on it, two at each cap).
fn walls_moved_build_their_prism(moves: &[(usize, f64, [f64; 3])]) {
let mut k = Kernel::default();
let Some(mut b) = solid(&mut k, "extrusion.smb") else {
return;
};
let faces = bp1::faces(&b, None).unwrap().len();
let planes = moved(&mut k, &mut b, moves).unwrap();
for (o, n) in planes {
let n = n * (1.0 / n.length());
let on: Vec<f64> = b
.vertex_list()
.iter()
.map(|&v| solidcore::topology::vertex::point(&b, v).unwrap())
.filter(|p| (*p - o).dot(n).abs() <= b.tolerance())
.map(|p| p.z)
.collect();
let at = |z: f64| {
on.iter()
.filter(|&&h| (h - z).abs() <= b.tolerance())
.count()
};
assert!(at(0.0) >= 2 && at(10.0) >= 2, "{on:?}");
}
assert!(solidcore::topology::brep::p2::is_manifold_solid(&b).unwrap());
assert_eq!(bp1::faces(&b, None).unwrap().len(), faces);
let v = volume(&mut k, &mut b).unwrap();
let bottom = cap_at(&k, &b, 0.0);
let want = 10.0 * face_area(&k, &mut b, bottom, ACCURACY).unwrap();
assert!((v - want).abs() <= AGREE * want, "{v} vs {want}");
}
/// gen0000: the quarter cylinder wall (face 4) given its tangent plane moved out 1.14, and
/// the cubic wall (face 2) its tangent plane at its middle. Each new plane meets the caps,
/// the flat wall beside them and the rational wall (face 5, an extrusion), whose ruled
/// extension past its end the moved planes reach.
#[test]
fn two_walls_given_planes_out_build_the_prism_of_their_profile() {
walls_moved_build_their_prism(&[(4, 1.143_604_136_567_873_7, [0.0; 3]), (2, 0.0, [0.0; 3])]);
}
/// gen0021: the same two walls, both moved out (0.20 and 0.55).
#[test]
fn two_walls_moved_out_build_the_prism_of_their_profile() {
walls_moved_build_their_prism(&[
(4, 0.202_101_138_781_204_4, [0.0; 3]),
(2, 0.548_365_023_570_791_1, [0.0; 3]),
]);
}
/// gen0048: the cubic wall (face 2) given its tangent plane at its middle.
#[test]
fn a_cubic_wall_given_its_tangent_plane_builds_the_prism_of_its_profile() {
walls_moved_build_their_prism(&[(2, 0.0, [0.0; 3])]);
}
/// gen0041: the top cap (face 1) moved down 0.16 and tilted. The walls keep their surfaces
/// and meet it along their rulings (the two extrusions as nets); the body is the solid over the
/// bottom cap under the tilted plane, whose volume is the cap's area times the plane's
/// height over the cap's centroid (the height is linear), and sound.
#[test]
fn a_top_moved_down_and_tilted_holds_its_height_over_the_centroid() {
let mut k = Kernel::default();
let Some(mut b) = solid(&mut k, "extrusion.smb") else {
return;
};
let bottom = cap_at(&k, &b, 0.0);
let (area, centroid) = face_centroid(&k, &mut b, bottom, ACCURACY).unwrap();
let tilt = [
-0.095_716_453_310_687_6,
0.014_193_158_954_830_198,
-0.155_603_183_282_545_88,
];
let planes = moved(&mut k, &mut b, &[(1, -0.163_195_178_504_810_47, tilt)]).unwrap();
assert!(solidcore::topology::brep::p2::is_manifold_solid(&b).unwrap());
// the plane's height over the centroid: (x − o)·n = 0 solved for z
let (o, n) = planes[0];
let height = o.z - ((centroid.x - o.x) * n.x + (centroid.y - o.y) * n.y) / n.z;
let want = area * height;
let v = volume(&mut k, &mut b).unwrap();
assert!((v - want).abs() <= AGREE * want, "{v} vs {want}");
}
/// gen0076: the base of `Solids/pyramid.smb` (a plane) moved up 1.31 toward the apex. Two
/// of the sides are nets off their planes by the rounding of their stored points (single
/// precision: 1.9e-6); the base meets them on their nets. What is left is the pyramid above
/// the new base, similar to the old one: the volume times `((h − d) / h)³`, `h` the apex's
/// height over the old base, `d` the move.
#[test]
fn a_pyramid_base_moved_up_leaves_the_similar_pyramid_above_it() {
let mut k = Kernel::default();
let Some(mut b) = solid(&mut k, "pyramid.smb") else {
return;
};
let before = volume(&mut k, &mut b).unwrap();
let h = b
.vertex_list()
.iter()
.map(|&v| solidcore::topology::vertex::point(&b, v).unwrap().z)
.fold(f64::NEG_INFINITY, f64::max);
let planes = moved(&mut k, &mut b, &[(0, 1.308_567_886_431_627_2, [0.0; 3])]).unwrap();
assert!(solidcore::topology::brep::p2::is_manifold_solid(&b).unwrap());
let d = planes[0].0.z;
assert!(d > 1.3 && d < 1.31, "{d}");
let want = before * ((h - d) / h).powi(3);
let v = volume(&mut k, &mut b).unwrap();
assert!((v - want).abs() <= AGREE * want, "{v} vs {want}");
}
/// The cases of `Solids/nurb_fillet.smb` that can leave a non-manifold body once the plane
/// beside its curved nets has a reach: built only as a manifold solid of positive volume,
/// or refused with the input as it came in (its volume, faces and edges).
fn sound_or_refused_unchanged(moves: &[(usize, f64, [f64; 3])]) {
let mut k = Kernel::default();
let Some(mut b) = solid(&mut k, "nurb_fillet.smb") else {
return;
};
let before = (
volume(&mut k, &mut b).unwrap(),
bp1::faces(&b, None).unwrap().len(),
b.edge_list().len(),
);
match moved(&mut k, &mut b, moves) {
Ok(_) => {
assert!(solidcore::topology::brep::p2::is_manifold_solid(&b).unwrap());
assert!(volume(&mut k, &mut b).unwrap() > 0.0);
}
Err(e) => {
let after = (
volume(&mut k, &mut b).unwrap(),
bp1::faces(&b, None).unwrap().len(),
b.edge_list().len(),
);
assert_eq!(after, before, "{e}");
}
}
}
/// `nurb_fillet_face0_same` (and its `attributed_` twin): face 0 given its tangent plane.
#[test]
fn a_curved_net_given_its_tangent_plane_is_sound_or_refused_unchanged() {
sound_or_refused_unchanged(&[(0, 0.0, [0.0; 3])]);
}
/// `nurb_fillet_face4_same` (and its `attributed_` twin): face 4 given its tangent plane.
#[test]
fn another_curved_net_given_its_tangent_plane_is_sound_or_refused_unchanged() {
sound_or_refused_unchanged(&[(4, 0.0, [0.0; 3])]);
}
/// `fc0004`: faces 16 and 0 given tilted planes, 16's moved in 1.21.
#[test]
fn two_curved_nets_given_tilted_planes_are_sound_or_refused_unchanged() {
sound_or_refused_unchanged(&[
(
16,
-1.212_618_021_690_697_2,
[
-0.227_499_561_725_195_12,
-0.119_235_175_885_283_43,
0.212_040_256_859_765_76,
],
),
(
0,
0.0,
[
0.195_822_407_983_586_08,
-0.180_816_552_666_528_46,
-0.250_316_266_099_896_8,
],
),
]);
}
@@ -0,0 +1,40 @@
# offset.offset_executive: a local operation's reach beside a bare B-spline net (2026-11-08)
Unit: `offset.offset_executive` (`local_extension_reach` in `offset_executive/reach.rs`, the
net in `reach/net.rs`), seen through `topology.brep_local_operation`.
**Cause.** The local operation's reach bounded a plane only against a plane, cylinder, cone or
sphere with an analytic label. A neighbour stored as a bare B-spline net (no label, no
definition) had no class, so the operation was refused as `ReachUncertified`. In
`Solids/extrusion.smb` two walls are extrusions with no label (of a cubic B-spline and of a
rational curve of lines and an arc). The four sides of `Solids/pyramid.smb` are bicubic nets
with a pole at the apex: faces 3 and 4 lie on a plane to 7.1e-15, faces 1 and 2 only to 1.9e-6
(their points are stored in single precision; the B-rep tolerance is 1.0e-3).
**The bound.** In each normal section of an edge, the plane's trace `x0 + τ u` meets the net
at a `(u, v, τ)`. Krawczyk's operator proves that meeting for every section of a piece of the
edge's parameters [Krawczyk 1969; Moore 1977], and the reach is `√(|x0 − p|² + τ²)`. Past a side,
the net is the extension the executive builds (`Ruled`): `H + s′ H_v` in homogeneous
coordinates, and `H + s′ H_u + t′ H_v + s′ t′ H_uv` past a corner, where both sides' rows end
in one weight ratio. A test checks this model against the built extension.
![In a normal section: the net's trace runs to the side of its box and on along the Ruled extension's line; the moved plane's trace meets that line, and the Krawczyk box around the meeting proves it.](offset.offset_executive--2978-reach-beside-nets/reach-beside-a-net.png)
*The meeting past the net's side, `τ` along the moved plane's trace from the foot `x0`.*
**Cases.** Seven cases of `topology.brep_local_operation` are built now, and each was refused
before: `gen0000`, `gen0021`, `gen0031`, `gen0041`, `gen0048` and `gen0059` (extrusion), and
`gen0076` (pyramid). Below, each is shown before (the input kept, the moved faces in blue) and
after, from the same view.
![gen0000](offset.offset_executive--2978-reach-beside-nets/gen0000.png)
![gen0021](offset.offset_executive--2978-reach-beside-nets/gen0021.png)
![gen0031](offset.offset_executive--2978-reach-beside-nets/gen0031.png)
![gen0041](offset.offset_executive--2978-reach-beside-nets/gen0041.png)
![gen0048](offset.offset_executive--2978-reach-beside-nets/gen0048.png)
![gen0059](offset.offset_executive--2978-reach-beside-nets/gen0059.png)
![gen0076](offset.offset_executive--2978-reach-beside-nets/gen0076.png)
**Still refused.** On the pyramid, eight cases move a side whose net ends in the apex pole.
They are still `ReachUncertified`, and the meeting left unproved there is not traced yet.
`tests/issue_2978_local_reach_beside_nets.rs` carries the closed-form volumes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="980" height="560" viewBox="0 0 980 560">
<title>A plane beside a net, in one normal section of the edge</title>
<g id="Layer_1" data-name="Layer 1">
<rect x="0" y="0" width="980" height="560" fill="#ffffff"/>
<text transform="matrix(1 0 0 1 24 44)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="20" font-weight="bold" fill="#000000"><tspan x="0" y="0">A plane beside a net, in one normal section of the edge</tspan></text>
<polygon points="330,470 328.594,463.525 327.375,457.1 326.344,450.725 325.5,444.4 324.844,438.125 324.375,431.9 324.094,425.725 324,419.6 324.094,413.525 324.375,407.5 324.844,401.525 325.5,395.6 326.344,389.725 327.375,383.9 328.594,378.125 330,372.4 331.594,366.725 333.375,361.1 335.344,355.525 337.5,350 339.844,344.525 342.375,339.1 345.094,333.725 348,328.4 351.094,323.125 354.375,317.9 357.844,312.725 361.5,307.6 365.344,302.525 369.375,297.5 373.594,292.525 378,287.6 382.594,282.725 387.375,277.9 392.344,273.125 397.5,268.4 402.844,263.725 408.375,259.1 414.094,254.525 420,250 170,250 170,470" fill="#f0f0f0"/>
<text transform="matrix(1 0 0 1 190 440)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#555555"><tspan x="0" y="0">the solid</tspan></text>
<polyline points="330,470 328.594,463.525 327.375,457.1 326.344,450.725 325.5,444.4 324.844,438.125 324.375,431.9 324.094,425.725 324,419.6 324.094,413.525 324.375,407.5 324.844,401.525 325.5,395.6 326.344,389.725 327.375,383.9 328.594,378.125 330,372.4 331.594,366.725 333.375,361.1 335.344,355.525 337.5,350 339.844,344.525 342.375,339.1 345.094,333.725 348,328.4 351.094,323.125 354.375,317.9 357.844,312.725 361.5,307.6 365.344,302.525 369.375,297.5 373.594,292.525 378,287.6 382.594,282.725 387.375,277.9 392.344,273.125 397.5,268.4 402.844,263.725 408.375,259.1 414.094,254.525 420,250" fill="none" stroke="#1f6fb2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="420" y1="250" x2="592" y2="121" fill="none" stroke="#1f6fb2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="9 6"/>
<line x1="386" y1="250" x2="454" y2="250" fill="none" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="6 4"/>
<path d="M416.5 250 C416.5 248.067 418.067 246.5 420 246.5 C421.933 246.5 423.5 248.067 423.5 250 C423.5 251.933 421.933 253.5 420 253.5 C418.067 253.5 416.5 251.933 416.5 250 Z" fill="#555555"/>
<text transform="matrix(1 0 0 1 434 272)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">the side of the net&apos;s box</tspan></text>
<line x1="150" y1="150" x2="860" y2="118" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<text transform="matrix(1 0 0 1 690 100)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">the moved plane&apos;s trace x0 + τ u</tspan></text>
<line x1="330" y1="470" x2="315.242" y2="142.552" fill="none" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="6 4"/>
<text transform="matrix(1 0 0 1 250 300)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">|x0 − p|</tspan></text>
<line x1="314.251" y1="120.575" x2="574.134" y2="108.862" fill="none" stroke="#555555" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
<polygon points="578.13,108.682 567.915,104.137 568.366,114.127" fill="#555555"/>
<text transform="matrix(1 0 0 1 443.181 106.606)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">τ</tspan></text>
<rect x="561.121" y="117.659" width="36" height="26" fill="#dce9f5" stroke="#555555" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="561.121" y1="131.471" x2="597.121" y2="129.848" fill="none" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<line x1="568.721" y1="138.459" x2="589.521" y2="122.859" fill="none" stroke="#1f6fb2" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="9 6"/>
<path d="M575.621 130.659 C575.621 128.726 577.188 127.159 579.121 127.159 C581.054 127.159 582.621 128.726 582.621 130.659 C582.621 132.592 581.054 134.159 579.121 134.159 C577.188 134.159 575.621 132.592 575.621 130.659 Z" fill="#000000"/>
<line x1="599.121" y1="142.659" x2="600" y2="210" fill="none" stroke="#999999" stroke-linecap="round" stroke-linejoin="round"/>
<text transform="matrix(1 0 0 1 606 206)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">Krawczyk&apos;s box Y: K(Y) inside Y</tspan></text>
<text transform="matrix(1 0 0 1 606 226)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">proves one meeting in it, for every</tspan></text>
<text transform="matrix(1 0 0 1 606 242)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">section of a piece of the edge</tspan></text>
<circle cx="330" cy="470" r="4.5" fill="#000000"/>
<text transform="matrix(1 0 0 1 342 476)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">p, a point of the edge</tspan></text>
<circle cx="315.242" cy="142.552" r="3.5" fill="#555555"/>
<text transform="matrix(1 0 0 1 285.242 128.552)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">x0</tspan></text>
<text transform="matrix(1 0 0 1 352 400)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">the net&apos;s trace</tspan></text>
<text transform="matrix(1 0 0 1 330 208)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">past the side: the</tspan></text>
<text transform="matrix(1 0 0 1 330 224)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">Ruled extension&apos;s line</tspan></text>
<text transform="matrix(1 0 0 1 560 420)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="14" fill="#000000"><tspan x="0" y="0">reach ≤ √(|x0 − p|² + τ²), the box&apos;s τ enclosed;</tspan></text>
<text transform="matrix(1 0 0 1 560 442)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">|τ| is the arc along the moved plane&apos;s trace</tspan></text>
<text transform="matrix(1 0 0 1 560 462)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">(over each piece of the edge&apos;s parameters,</tspan></text>
<text transform="matrix(1 0 0 1 560 478)" x="0" y="0" xml:space="preserve" font-family="Helvetica, sans-serif" font-size="12" fill="#000000"><tspan x="0" y="0">the foot and the direction by their mean values)</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB