2
$\begingroup$
 polygonsData={{{-207.407,511.227,-111.583},{-206.865,510.999,-111.583},{-207.744,511.184,-112.063}},{{-210.623,503.579,-108.641},{-207.407,511.227,-111.583},{-207.744,511.184,-112.063}},{{-207.744,511.184,-112.063},{-210.96,503.536,-109.122},{-210.623,503.579,-108.641}},{{-210.96,503.536,-109.122},{-207.744,511.184,-112.063},{-207.539,510.913,-112.543}},{{-206.997,510.685,-112.543},{-207.539,510.913,-112.543},{-207.744,511.184,-112.063}},{{-206.66,510.728,-112.063},{-206.997,510.685,-112.543},{-207.744,511.184,-112.063}},{{-206.865,510.999,-111.583},{-206.66,510.728,-112.063},{-207.744,511.184,-112.063}},{{-206.865,510.999,-111.583},{-210.081,503.351,-108.641},{-209.876,503.08,-109.122}},{{-210.081,503.351,-108.641},{-206.865,510.999,-111.583},{-207.407,511.227,-111.583}},{{-209.876,503.08,-109.122},{-206.66,510.728,-112.063},{-206.865,510.999,-111.583}},{{-206.66,510.728,-112.063},{-209.876,503.08,-109.122},{-210.213,503.037,-109.602}},{{-209.876,503.08,-109.122},{-210.081,503.351,-108.641},{-210.96,503.536,-109.122}},{{-210.96,503.536,-109.122},{-210.213,503.037,-109.602},{-209.876,503.08,-109.122}},{{-206.997,510.685,-112.543},{-210.213,503.037,-109.602},{-210.755,503.265,-109.602}},{{-210.213,503.037,-109.602},{-206.997,510.685,-112.543},{-206.66,510.728,-112.063}},{{-210.755,503.265,-109.602},{-210.213,503.037,-109.602},{-210.96,503.536,-109.122}},{{-207.539,510.913,-112.543},{-210.755,503.265,-109.602},{-210.96,503.536,-109.122}},{{-210.755,503.265,-109.602},{-207.539,510.913,-112.543},{-206.997,510.685,-112.543}},{{-207.407,511.227,-111.583},{-210.623,503.579,-108.641},{-210.081,503.351,-108.641}},{{-210.081,503.351,-108.641},{-210.623,503.579,-108.641},{-210.96,503.536,-109.122}},{{-207.566,510.85,-104.259},{-207.024,510.622,-104.259},{-207.744,511.184,-104.709}},{{-210.782,503.201,-108.672},{-207.566,510.85,-104.259},{-207.744,511.184,-104.709}},{{-207.744,511.184,-104.709},{-210.96,503.536,-109.122},{-210.782,503.201,-108.672}},{{-210.96,503.536,-109.122},{-207.744,511.184,-104.709},{-207.38,511.291,-105.159}},{{-206.838,511.063,-105.159},{-207.38,511.291,-105.159},{-207.744,511.184,-104.709}},{{-206.66,510.728,-104.709},{-206.838,511.063,-105.159},{-207.744,511.184,-104.709}},{{-207.024,510.622,-104.259},{-206.66,510.728,-104.709},{-207.744,511.184,-104.709}},{{-207.024,510.622,-104.259},{-210.239,502.973,-108.672},{-209.876,503.08,-109.122}},{{-210.239,502.973,-108.672},{-207.024,510.622,-104.259},{-207.566,510.85,-104.259}},{{-209.876,503.08,-109.122},{-206.66,510.728,-104.709},{-207.024,510.622,-104.259}},{{-206.66,510.728,-104.709},{-209.876,503.08,-109.122},{-210.054,503.414,-109.571}},{{-209.876,503.08,-109.122},{-210.239,502.973,-108.672},{-210.96,503.536,-109.122}},{{-210.96,503.536,-109.122},{-210.054,503.414,-109.571},{-209.876,503.08,-109.122}},{{-206.838,511.063,-105.159},{-210.054,503.414,-109.571},{-210.596,503.643,-109.571}},{{-210.054,503.414,-109.571},{-206.838,511.063,-105.159},{-206.66,510.728,-104.709}},{{-210.596,503.643,-109.571},{-210.054,503.414,-109.571},{-210.96,503.536,-109.122}},{{-207.38,511.291,-105.159},{-210.596,503.643,-109.571},{-210.96,503.536,-109.122}},{{-210.596,503.643,-109.571},{-207.38,511.291,-105.159},{-206.838,511.063,-105.159}},{{-207.566,510.85,-104.259},{-210.782,503.201,-108.672},{-210.239,502.973,-108.672}},{{-210.239,502.973,-108.672},{-210.782,503.201,-108.672},{-210.96,503.536,-109.122}}}

Graphics3D[Polygon@polygonsData]

My question is how can I split mesh [the two joined rods] into two rods?

One possible method is using cloud point split, something like semantic segment, the basic primitive part is the rod or cuboid.

Are there any solutions that can be used via wolfram tech?

Or any other simple methods to do such tasks?

In the joint place, we can also use a sphere or cuboid to connect two rods, if it's hard to split the joint place.

enter image description here

enter image description here some samples data

{{{-193.345,520.705,-97.7087},{-193.086,520.347,-97.7087},{-193.488,520.874,-98.0905}},{{-199.848,516.008,-97.3474},{-193.345,520.705,-97.7087},{-193.488,520.874,-98.0905}},{{-193.488,520.874,-98.0905},{-199.848,516.28,-97.7371},{-199.848,516.008,-97.3474}},{{-199.848,516.28,-97.7371},{-193.488,520.874,-98.0905},{-193.373,520.685,-98.4722}},{{-193.114,520.327,-98.4722},{-193.373,520.685,-98.4722},{-193.488,520.874,-98.0905}},{{-192.971,520.158,-98.0905},{-193.114,520.327,-98.4722},{-193.488,520.874,-98.0905}},{{-193.086,520.347,-97.7087},{-192.971,520.158,-98.0905},{-193.488,520.874,-98.0905}},{{-193.086,520.347,-97.7087},{-199.848,515.464,-97.3331},{-199.848,515.192,-97.7084}},{{-199.848,515.464,-97.3331},{-193.086,520.347,-97.7087},{-193.345,520.705,-97.7087}},{{-199.848,515.192,-97.7084},{-192.971,520.158,-98.0905},{-193.086,520.347,-97.7087}},{{-192.971,520.158,-98.0905},{-199.848,515.192,-97.7084},{-199.848,515.464,-98.0981}},{{-206.725,520.158,-98.0905},{-199.848,515.192,-97.7084},{-199.848,515.464,-97.3331}},{{-206.582,520.327,-98.4722},{-199.848,515.464,-98.0981},{-199.848,515.192,-97.7084}},{{-199.848,515.192,-97.7084},{-206.725,520.158,-98.0905},{-206.582,520.327,-98.4722}},{{-199.848,515.464,-98.0981},{-206.582,520.327,-98.4722},{-206.324,520.685,-98.4722}},{{-206.208,520.874,-98.0905},{-206.582,520.327,-98.4722},{-206.725,520.158,-98.0905}},{{-206.324,520.685,-98.4722},{-206.582,520.327,-98.4722},{-206.208,520.874,-98.0905}},{{-206.208,520.874,-98.0905},{-199.848,516.28,-97.7371},{-199.848,516.008,-98.1125}},{{-199.848,516.28,-97.7371},{-206.208,520.874,-98.0905},{-206.351,520.705,-97.7087}},{{-206.61,520.347,-97.7087},{-206.351,520.705,-97.7087},{-206.208,520.874,-98.0905}},{{-199.848,516.008,-98.1125},{-206.324,520.685,-98.4722},{-206.208,520.874,-98.0905}},{{-206.725,520.158,-98.0905},{-206.61,520.347,-97.7087},{-206.208,520.874,-98.0905}},{{-199.848,515.464,-97.3331},{-206.61,520.347,-97.7087},{-206.725,520.158,-98.0905}},{{-206.61,520.347,-97.7087},{-199.848,515.464,-97.3331},{-199.848,516.008,-97.3474}},{{-199.848,516.008,-97.3474},{-206.351,520.705,-97.7087},{-206.61,520.347,-97.7087}},{{-193.373,520.685,-98.4722},{-199.848,516.008,-98.1125},{-199.848,516.28,-97.7371}},{{-199.848,516.008,-98.1125},{-193.373,520.685,-98.4722},{-193.114,520.327,-98.4722}},{{-193.114,520.327,-98.4722},{-199.848,515.464,-98.0981},{-199.848,516.008,-98.1125}},{{-206.324,520.685,-98.4722},{-199.848,516.008,-98.1125},{-199.848,515.464,-98.0981}},{{-206.351,520.705,-97.7087},{-199.848,516.008,-97.3474},{-199.848,516.28,-97.7371}},{{-199.848,515.464,-98.0981},{-193.114,520.327,-98.4722},{-192.971,520.158,-98.0905}},{{-193.345,520.705,-97.7087},{-199.848,516.008,-97.3474},{-199.848,515.464,-97.3331}}}


{{{-199.627,510.574,-112.063},{-200.069,510.574,-112.063},{-199.407,510.956,-112.063}},{{-199.627,510.574,-104.93},{-199.627,510.574,-112.063},{-199.407,510.956,-112.063}},{{-199.407,510.956,-112.063},{-199.407,510.956,-105.15},{-199.627,510.574,-104.93}},{{-199.407,510.956,-105.15},{-199.407,510.956,-112.063},{-199.627,511.338,-112.063}},{{-200.069,511.338,-112.063},{-199.627,511.338,-112.063},{-199.407,510.956,-112.063}},{{-200.289,510.956,-112.063},{-200.069,511.338,-112.063},{-199.407,510.956,-112.063}},{{-200.069,510.574,-112.063},{-200.289,510.956,-112.063},{-199.407,510.956,-112.063}},{{-200.069,510.574,-112.063},{-200.069,510.574,-104.488},{-200.289,510.956,-104.268}},{{-200.069,510.574,-104.488},{-200.069,510.574,-112.063},{-199.627,510.574,-112.063}},{{-200.289,510.956,-104.268},{-200.289,510.956,-112.063},{-200.069,510.574,-112.063}},{{-200.289,510.956,-112.063},{-200.289,510.956,-104.268},{-200.069,511.338,-104.488}},{{-192.494,510.956,-104.268},{-200.289,510.956,-104.268},{-200.069,510.574,-104.488}},{{-192.494,511.338,-104.488},{-200.069,511.338,-104.488},{-200.289,510.956,-104.268}},{{-200.289,510.956,-104.268},{-192.494,510.956,-104.268},{-192.494,511.338,-104.488}},{{-200.069,511.338,-104.488},{-192.494,511.338,-104.488},{-192.494,511.338,-104.93}},{{-192.494,510.956,-105.15},{-192.494,511.338,-104.488},{-192.494,510.956,-104.268}},{{-192.494,511.338,-104.93},{-192.494,511.338,-104.488},{-192.494,510.956,-105.15}},{{-192.494,510.956,-105.15},{-199.407,510.956,-105.15},{-199.627,511.338,-104.93}},{{-199.407,510.956,-105.15},{-192.494,510.956,-105.15},{-192.494,510.574,-104.93}},{{-192.494,510.574,-104.488},{-192.494,510.574,-104.93},{-192.494,510.956,-105.15}},{{-199.627,511.338,-104.93},{-192.494,511.338,-104.93},{-192.494,510.956,-105.15}},{{-192.494,510.956,-104.268},{-192.494,510.574,-104.488},{-192.494,510.956,-105.15}},{{-200.069,510.574,-104.488},{-192.494,510.574,-104.488},{-192.494,510.956,-104.268}},{{-192.494,510.574,-104.488},{-200.069,510.574,-104.488},{-199.627,510.574,-104.93}},{{-199.627,510.574,-104.93},{-192.494,510.574,-104.93},{-192.494,510.574,-104.488}},{{-199.627,511.338,-112.063},{-199.627,511.338,-104.93},{-199.407,510.956,-105.15}},{{-199.627,511.338,-104.93},{-199.627,511.338,-112.063},{-200.069,511.338,-112.063}},{{-200.069,511.338,-112.063},{-200.069,511.338,-104.488},{-199.627,511.338,-104.93}},{{-192.494,511.338,-104.93},{-199.627,511.338,-104.93},{-200.069,511.338,-104.488}},{{-192.494,510.574,-104.93},{-199.627,510.574,-104.93},{-199.407,510.956,-105.15}},{{-200.069,511.338,-104.488},{-200.069,511.338,-112.063},{-200.289,510.956,-112.063}},{{-199.627,510.574,-112.063},{-199.627,510.574,-104.93},{-200.069,510.574,-104.488}},{{-200.069,510.574,-97.3551},{-199.627,510.574,-97.3551},{-200.289,510.956,-97.3551}},{{-200.069,510.574,-104.488},{-200.069,510.574,-97.3551},{-200.289,510.956,-97.3551}},{{-200.289,510.956,-97.3551},{-200.289,510.956,-104.268},{-200.069,510.574,-104.488}},{{-200.289,510.956,-104.268},{-200.289,510.956,-97.3551},{-200.069,511.338,-97.3551}},{{-199.627,511.338,-97.3551},{-200.069,511.338,-97.3551},{-200.289,510.956,-97.3551}},{{-199.407,510.956,-97.3551},{-199.627,511.338,-97.3551},{-200.289,510.956,-97.3551}},{{-199.627,510.574,-97.3551},{-199.407,510.956,-97.3551},{-200.289,510.956,-97.3551}},{{-199.627,510.574,-97.3551},{-199.627,510.574,-104.93},{-199.407,510.956,-105.15}},{{-199.627,510.574,-104.93},{-199.627,510.574,-97.3551},{-200.069,510.574,-97.3551}},{{-199.407,510.956,-105.15},{-199.407,510.956,-97.3551},{-199.627,510.574,-97.3551}},{{-199.407,510.956,-97.3551},{-199.407,510.956,-105.15},{-199.627,511.338,-104.93}},{{-207.202,510.956,-105.15},{-199.407,510.956,-105.15},{-199.627,510.574,-104.93}},{{-207.202,511.338,-104.93},{-199.627,511.338,-104.93},{-199.407,510.956,-105.15}},{{-199.407,510.956,-105.15},{-207.202,510.956,-105.15},{-207.202,511.338,-104.93}},{{-199.627,511.338,-104.93},{-207.202,511.338,-104.93},{-207.202,511.338,-104.488}},{{-207.202,510.956,-104.268},{-207.202,511.338,-104.93},{-207.202,510.956,-105.15}},{{-207.202,511.338,-104.488},{-207.202,511.338,-104.93},{-207.202,510.956,-104.268}},{{-207.202,510.956,-104.268},{-200.289,510.956,-104.268},{-200.069,511.338,-104.488}},{{-200.289,510.956,-104.268},{-207.202,510.956,-104.268},{-207.202,510.574,-104.488}},{{-207.202,510.574,-104.93},{-207.202,510.574,-104.488},{-207.202,510.956,-104.268}},{{-200.069,511.338,-104.488},{-207.202,511.338,-104.488},{-207.202,510.956,-104.268}},{{-207.202,510.956,-105.15},{-207.202,510.574,-104.93},{-207.202,510.956,-104.268}},{{-199.627,510.574,-104.93},{-207.202,510.574,-104.93},{-207.202,510.956,-105.15}},{{-207.202,510.574,-104.93},{-199.627,510.574,-104.93},{-200.069,510.574,-104.488}},{{-200.069,510.574,-104.488},{-207.202,510.574,-104.488},{-207.202,510.574,-104.93}},{{-200.069,511.338,-97.3551},{-200.069,511.338,-104.488},{-200.289,510.956,-104.268}},{{-200.069,511.338,-104.488},{-200.069,511.338,-97.3551},{-199.627,511.338,-97.3551}},{{-199.627,511.338,-97.3551},{-199.627,511.338,-104.93},{-200.069,511.338,-104.488}},{{-207.202,511.338,-104.488},{-200.069,511.338,-104.488},{-199.627,511.338,-104.93}},{{-207.202,510.574,-104.488},{-200.069,510.574,-104.488},{-200.289,510.956,-104.268}},{{-199.627,511.338,-104.93},{-199.627,511.338,-97.3551},{-199.407,510.956,-97.3551}},{{-200.069,510.574,-97.3551},{-200.069,510.574,-104.488},{-199.627,510.574,-104.93}}}

The data is got by real complex 3D model by ConnectedMeshComponents, the connected rods mesh may share common points.

The final purpose is use some BoundingBox to repair some parts of the model which are not so straight or not closed[with holes].

$\endgroup$
2
  • $\begingroup$ If you could make a restriction like: no two cylinder have a common point, the problem becomes much easier. $\endgroup$ Commented Sep 23, 2022 at 14:15
  • $\begingroup$ @DanielHuber I think this condition is OK. But if we Bounding two meshes with Cylinders, the two cylinders may have some intersection. $\endgroup$ Commented Sep 23, 2022 at 15:25

2 Answers 2

2
$\begingroup$

Given the input polygon is in polygon (with Polygon head), this hack finds approximate lines aligning with cylinders, identifies caps in a bit of an ad hoc manner, and then identifies corresponding cylinder bodies on basis of mean distance to lines:

Module[{lines, caps, nocaps, lineofpoly},
 (* Compute lines which have minimal distance to a random point
    set on the surface of polygons. *)
 lines =
  {InfiniteLine[{x1, y1, z1}, {u1, v1, w1}],
   InfiniteLine[{x2, y2, z2}, {u2, v2, w2}]} /.
   (* Repeat until threshold for true minimum is met. *)
   Last@NestWhile[
     With[
       {pts = RandomPoint[polygon, 100]},
       NMinimize[
        (* Squared euclidean norm. *)
        Total[RegionDistance[
           RegionUnion[
            InfiniteLine[{x1, y1, z1}, {u1, v1, w1}],
            InfiniteLine[{x2, y2, z2}, {u2, v2, w2}]],
           pts]^2],
        (* Lines must pass through the region,
           with unit direction vectors. *)
        {Element[{x1, y1, z1}, Cuboid @@ CoordinateBoundingBox[pts]],
         Element[{x2, y2, z2}, Cuboid @@ CoordinateBoundingBox[pts]],
         Element[{u1, v1, w1}, Sphere[]],
         Element[{u2, v2, w2}, Sphere[]]}]] &,
     {Infinity, {}},
     (* Threshold for successful minimization. *)
     Apply[#1/100 > 1^2 &]];
 (* Find caps, small polygons which are almost perpendicular to 
    a specific line. *)
 caps =
  Table[
   Select[First[polygon],
    Area[Polygon[#]] < 1 &&
      (* line[[2]] is the infinite line direction,
         Cross computes polygon normal. *)
      Abs[line[[2]] . Normalize[Cross @@ Differences[#[[;; 3]]]]] > 
       0.9 &],
   {line, lines}];
 (* Join caps with their corresponding bodies. *)
 MapThread[Polygon@*Join,
   {caps,
    (* Caps removed, gather polygons per closest line on basis
       of mean distance. *)
    nocaps = Complement[First[polygon], Flatten[caps, 1]];
    (* Find the closest line for each polygon. *)
    lineofpoly =
     Table[
      First@Nearest[lines, Polygon[p],
        DistanceFunction ->
         (* Line-polygon distance measure over the polygon. *)
         (Quiet@NIntegrate[
             RegionDistance[#2, {x, y, z}],
             Element[{x, y, z}, #1]] &)],
      {p, nocaps}];
    Table[
     (* Divide polygons to lists according to lines. *)
     Extract[nocaps, Position[lineofpoly, line, 1]],
     {line, lines}]}]]

This results two separated Polygons:

Graphics3D[Riffle[{Red, Green}, %]]

enter image description here

enter image description here

enter image description here

It's hard to get the last example reliably right, NMinimize finding a local minimum with a large likelihood. This is fixed by just retrying with new random points if solution doesn't meet a threshold (which could be reasoned in this case quite easily from cylinder radius).

$\endgroup$
1
$\begingroup$

To separate the cylinders we request the additional restriction that no two cylinders can share a point.

With the above mentioned restriction we first create some sample data triangles: polys

p = Partition[CirclePoints[6], 2, 1, {1, 1}, CirclePoints[6][[{1}]]];
h = 10;
p = {{Append[#[[1]], 0], Append[#[[2]], 0], 
      Append[#[[1]], h]}, {Append[#[[1]], h], Append[#[[2]], h], 
      Append[#[[2]], 0]}} & /@ p;
p1 = Flatten[p, 1];
p2 = p1 /. 
   x : {_?NumericQ, _, _} :> 
    RotationMatrix[{{0, 0, 1}, {1, 1, 1}}] . x;
p3 = p1 /. 
   x : {_?NumericQ, _, _} :> 
    RotationMatrix[{{0, 0, 1}, {1, 1, 0}}] . x;
polys = Join[p1, p2, p3];
Graphics3D[Polygon@polys]

enter image description here

To separate the different cylinders, we pick the first triangle and select sequentially all triangles that have some points common points with the already found triangles. This gives the first cylinder. We then delete all triangles from the original list and start over.

res = {};
While[polys != {},
 dat = new = {polys[[1]]};
 dat0 = polys[[2 ;;]];
 While[new != {},
  new = Select[
    dat0, (MemberQ[Flatten[new, 1], #[[1]] | #[[2]] | #[[3]]]) &];
  dat = Join[dat, new];
  dat0 = Complement[dat0, new];
  ];
 AppendTo[res, dat];
 polys = Complement[polys, dat];
 ]

Graphics3D[Polygon[#], Axes -> True] & /@ res

enter image description here

$\endgroup$
1
  • $\begingroup$ Sorry, I misunderstood that the result cylinders share no common points. In this kind, it's much simpler could also be done by DiscretizeGraphics@gg // ConnectedMeshComponents $\endgroup$ Commented Sep 24, 2022 at 0:56

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.