1
$\begingroup$

Given that I have a triangular mesh model defined in obj format (1590 vertices and 300 faces), I reconstruct it to a single B-spline surface.

enter image description here

Now I want to export the generated B-spline surface to a triangular mesh similar to the original one.

Surface definition

Due to the stack website limiting the number of characters, please download it from https://github.com/LavenderNPU/Test/blob/main/control-points-40x40.csv

P = Partition[Import["local-file", "CSV"], 40); (* due to stack website limits the number of the characters, please download it from https://github.com/LavenderNPU/Test/blob/main/control-points-40x40.csv *)
U = {0,0,0,0,0.027027,0.0540541,0.0810811,0.108108,0.135135,0.162162,0.189189,0.216216,0.243243,0.27027,0.297297,0.324324,0.351351,0.378378,0.405405,0.432432,0.459459,0.486486,0.513514,0.540541,0.567568,0.594595,0.621622,0.648649,0.675676,0.702703,0.72973,0.756757,0.783784,0.810811,0.837838,0.864865,0.891892,0.918919,0.945946,0.972973,1,1,1,1};
V = {0,0,0,0,0.027027,0.0540541,0.0810811,0.108108,0.135135,0.162162,0.189189,0.216216,0.243243,0.27027,0.297297,0.324324,0.351351,0.378378,0.405405,0.432432,0.459459,0.486486,0.513514,0.540541,0.567568,0.594595,0.621622,0.648649,0.675676,0.702703,0.72973,0.756757,0.783784,0.810811,0.837838,0.864865,0.891892,0.918919,0.945946,0.972973,1,1,1,1};
mask = BSplineFunction[P, SplineDegree -> {3, 3}, SplineKnots -> {U, V}];

ParametricPlot3D[f[u, v], {u, 0, 1}, {v, 0, 1}, PlotPoints -> 50]

Trial-1

p2 = Graphics3D@First@ParametricPlot3D[f[u, v], {u, 0, 1}, {v, 0, 1}, PlotPoints -> 50];
DiscretizeGraphics[Normal[p2 /. (Lighting -> _) :> Lighting -> Automatic]]

enter image description here

Obviously, the quality of DiscretizeGraphics[] is lower than the original one.

Trial-2

 ParametricPlot3D[f[u, v], {u, 0, 1}, {v, 0, 1}, PlotPoints -> 30, Mesh -> All]

 Export["mask-mma.obj", %]

enter image description here

However, PlotPoints -> 30 and Mesh -> All will introduce more vertices (2859) than the original obj file (1590 vertices).

So I would like to know if there is a proper method to generate a triangular mesh similar to the original one (fewer vertices and good triangle distribution)

$\endgroup$
5
  • $\begingroup$ Your f[u,v] is undefined. Perhaps you need to edit your question. $\endgroup$ Commented Feb 18, 2023 at 15:01
  • $\begingroup$ The code doesn't work, Maybe the best way is directly post U and V or P. $\endgroup$
    – cvgmt
    Commented Feb 18, 2023 at 15:30
  • $\begingroup$ @cvgmt Sorry for the missing data. I have updated the question. The P is very large and the stack site limits the number of characters, please download it to PC and then import it. $\endgroup$
    – Lavender
    Commented Feb 19, 2023 at 3:04
  • $\begingroup$ Have you tried OpenCascadeLink? $\endgroup$
    – user21
    Commented Feb 19, 2023 at 7:44
  • $\begingroup$ @user21 No, thanks for your suggestion. $\endgroup$
    – Lavender
    Commented Feb 19, 2023 at 10:59

1 Answer 1

2
$\begingroup$
  • Not an answer. Since the original code does not run, here we modified some part of the code.
  • ArrayReshape the data P to 40*40*3 since there are 1600 points.
  • Replace the download link of the data P.
Clear[P, U, V, mask];
P = Import[
   "https://raw.githubusercontent.com/LavenderNPU/Test/main/control-\
points-40x40.csv", "CSV"];
U = {0, 0, 0, 0, 0.027027, 0.0540541, 0.0810811, 0.108108, 0.135135, 
   0.162162, 0.189189, 0.216216, 0.243243, 0.27027, 0.297297, 
   0.324324, 0.351351, 0.378378, 0.405405, 0.432432, 0.459459, 
   0.486486, 0.513514, 0.540541, 0.567568, 0.594595, 0.621622, 
   0.648649, 0.675676, 0.702703, 0.72973, 0.756757, 0.783784, 
   0.810811, 0.837838, 0.864865, 0.891892, 0.918919, 0.945946, 
   0.972973, 1, 1, 1, 1};
V = {0, 0, 0, 0, 0.027027, 0.0540541, 0.0810811, 0.108108, 0.135135, 
   0.162162, 0.189189, 0.216216, 0.243243, 0.27027, 0.297297, 
   0.324324, 0.351351, 0.378378, 0.405405, 0.432432, 0.459459, 
   0.486486, 0.513514, 0.540541, 0.567568, 0.594595, 0.621622, 
   0.648649, 0.675676, 0.702703, 0.72973, 0.756757, 0.783784, 
   0.810811, 0.837838, 0.864865, 0.891892, 0.918919, 0.945946, 
   0.972973, 1, 1, 1, 1};
mask = BSplineFunction[ArrayReshape[P, {40, 40, 3}], 
   SplineDegree -> {3, 3}, SplineKnots -> {U, V}];
surf = ParametricPlot3D[mask[u, v], {u, 0, 1}, {v, 0, 1}, 
  PlotPoints -> 50]
  • MaxRecursion -> 0 can prevent Mathematica to add extra points.
surf1 = ParametricPlot3D[mask[u, v], {u, 0, 1}, {v, 0, 1}, 
  PlotPoints -> 30, Mesh -> All, MaxRecursion -> 0]
Export["mask-mma.obj", surf1]
  • It seems that DiscretizeGraphics only support polygon, does not using B-Spline surface as the basic element. According to the DiscretizeGraphics document,"Nonlinear Graphics primitives can only be approximately represented"
Graphics3D[
 BSplineSurface[Partition[P, 40], SplineDegree -> {3, 3}, 
  SplineKnots -> {U, V}]]
$\endgroup$
1
  • $\begingroup$ cvgmt, thanks for making it work. $\endgroup$
    – Lavender
    Commented Feb 19, 2023 at 4:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.