7
$\begingroup$

I want to make some 2D version of 3D particles. I used to shrinkWrap the 3D mesh to a plan, and draw NURBS curve manually along the boundary. However it is too time-consuming!

enter image description here

Is there any easy way to extract the 2D curve, i.e. the orange outline shown above, or clean the internal vertices of a shrink-wrapped mesh?

Update: The knife project tool is not usable in my case, as the mesh consists of 20k+ vertices. The blender seems "dead" when using it.

$\endgroup$
  • 1
    $\begingroup$ Possible duplicate of Turning a complex 3d object into a 2d contour $\endgroup$ – Duarte Farrajota Ramos Oct 23 '18 at 17:33
  • $\begingroup$ Also see blender.stackexchange.com/questions/77279/… $\endgroup$ – Duarte Farrajota Ramos Oct 23 '18 at 17:35
  • $\begingroup$ The knife project tool is so slow! I tested it with a coarse mesh of 6000 vertices, but no response for few minutes. $\endgroup$ – KOF Oct 23 '18 at 18:09
  • 1
    $\begingroup$ Could you just use a BoolTool Intersect with a simple plane sharing same center? I don't see much of a problem here for me, but I am not sure about your computer specs being a limitation with your mesh object resolutions.... $\endgroup$ – Craig D Jones Oct 31 '18 at 18:59
  • 4
    $\begingroup$ How about rendering this object with the simplest emission material and ortho camera. Then convert image to .svg $\endgroup$ – Serge L Oct 31 '18 at 19:09
7
+50
$\begingroup$

Bmesh Approach

  • Projecting onto a plane such that proj is our vector normal to the plane and the bounding box center is on the plane.
  • Split mesh into two sets of vertices those with normals pointing towards and away from proj
  • Project them onto the two planes each side of projection planeenter image description here Local Y projection of random icosphere "flatrock" showing intermediate result with scale_factor thickness 1, and silhouette edge mesh in orange
  • Bisect the new flat ended mesh, keeping only the bisection result.

Test Script, projects using the local Y axis producing a front on silhouette mesh that can be converted to curve. Adjust proj (could use 3d view matrix) and scale_factor which controls the thickness of flattened mesh.

Edit: Updated for 2.8. For prior version see revision 5

import bpy
import bmesh
from mathutils import Vector, Matrix

context = bpy.context
scene = context.scene
viewlayer = context.view_layer
ob = context.object
me = ob.data
bm = bmesh.new()
bm.from_mesh(me)
scale_factor = 0.1
c  = sum((Vector(b) for b in ob.bound_box), Vector()) / 8   

proj = Vector((0, 1, 0)).normalized()
T = Matrix.Translation(-c)
S = Matrix.Scale(0, 4, proj)
verts = [v for v in bm.verts if v.normal.dot(proj) > 0]
bmesh.ops.transform(bm, matrix=S, verts=verts, 
        space=Matrix.Translation(-c - scale_factor * proj))
bmesh.ops.transform(bm, matrix=S, verts=list(set(bm.verts) - set(verts)), 
        space=Matrix.Translation(-c + scale_factor * proj))

#bm.to_mesh(me)
bmesh.ops.bisect_plane(bm, geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
        plane_co=c,
        plane_no=proj,
        clear_inner=True,
        clear_outer=True)

copy = ob.copy()
sil = bpy.data.meshes.new("silhouette")
copy.data = sil
scene.collection.objects.link(copy)
viewlayer.objects.active = copy
copy.select_set(True)
bm.to_mesh(sil)

enter image description here This time showing result of looping on 3 principal local axes for proj in Matrix.Identity(3):

enter image description here Y projection of Suzanne. Showing how backfaces on opposite side of planes create some internal geometry which could be tested for and ignored enter image description here result of script on object with 60K+ verts ran in a couple of seconds on old computer

|improve this answer|||||
$\endgroup$
  • $\begingroup$ Can you please refine the 3D mesh into ~30000 vertices, and test the performance? $\endgroup$ – KOF Nov 1 '18 at 17:13
  • $\begingroup$ Very clever indeed,,, $\endgroup$ – Robin Betts Nov 3 '18 at 1:26
4
$\begingroup$

Did you try freestyle - export to svg? https://docs.blender.org/manual/fi/dev/render/freestyle/export_svg.html

enter image description here

|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ What I want to do is to extract a clean 2D mesh. $\endgroup$ – KOF Nov 1 '18 at 13:01
  • 4
    $\begingroup$ You could then import the SVG file. It's at least worth trying and comparing the results to other approaches. $\endgroup$ – risingfall Nov 1 '18 at 16:05
  • $\begingroup$ theres the non blender way, it may apply. render your image shadeles with alpha background inkskape [ inkscape.org/es/release/0.92.3 ] inkskape have a function to convert bitmaps to svg curves check this: [youtube.com/watch?v=kMewvFYPOdM] then import it back as inkscape saves svg files. $\endgroup$ – Javier Nov 2 '18 at 4:20
  • $\begingroup$ I think this is a very clean approach.. getting Freestyle to do all the work.. and you can tune it by adjusting segment lengths, simplifying curvature, using all the modifiers available - all within Blender. $\endgroup$ – Robin Betts Nov 3 '18 at 1:25
  • $\begingroup$ if you dont need it explicitelly as an svg curve. why not to try the boolean modifier to extract a section of your mesh. Use a plane to get the intersection section you want. look at this may be this is what you need youtube.com/watch?v=gEudXbZQzIA $\endgroup$ – Javier Nov 4 '18 at 2:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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