[Closed] A little challenge: Make a shell without Shell Modifier
Outer Shell only for meshes could be something like:
(
outer = 10.0
segs = 3
faces = $.faces as bitarray
meshop.cloneFaces $ #all
for j = 1 to segs do meshop.extrudeFaces $ #selection (outer/segs) 0.0 dir:#independent
update $
)
Without Segments:
(
outer = 10.0
faces = $.faces as bitarray
meshop.cloneFaces $ #all
meshop.extrudeFaces $ #selection outer 0.0 dir:#independent
update $
)
Didn’t really tested it much.
For Inner Shell it would be a little more elaborated, but pretty much the same.
very close… but not correct
and… there is a problem. what can be shelled?
Is it because of the not welded vertices and flipped faces or is there anything else you are looking for?
(
outer = 5.0
segs = 3
faces = $.faces as bitarray
meshop.cloneFaces $ #all
for j = 1 to segs do meshop.extrudeFaces $ #selection (outer/segs) 0.0 dir:#independent
meshop.flipNormals $ faces
meshop.weldVertsByThreshold $ (meshop.getvertsusingedge $ (meshop.getopenedges $)) 0.0001
update $
)
you are doing everything right. but…
let’s use this sample scene:
delete objects
sp = converttomesh (sphere name:"s" radius:10 segments:24)
meshop.detachfaces sp #{1..264}
meshop.deletefaces sp #{1..120, 145..168, 193..216, 241..264, 289..312, 337..360, 385..528}
update sp
there are two elements… so you have to make two shells.
(
outer = 2.0
meshop.cloneFaces sp #all
meshop.flipNormals sp #selection
meshop.extrudeFaces sp #selection outer 0.0 dir:#independent
-- meshop.weldVertsByThreshold sp ...
update sp
)
and second is… look at these shells. is any way to make shelled faces seamless? (shell modifier can’t do it).
don’t worry now about seamless normals. but try to have “edge” vertices on same positions for both shells.
Here is a little more complete function:
(
fn ShellMesh node inner:0.0 outer:0.0 segments:1 inMat: outMat: edgeMat: =
(
inFaces = node.faces as bitarray
meshop.flipNormals node #all
meshop.extrudeFaces node #all inner 0.0 dir:#independent
meshop.deletefaces node (node.faces as bitarray - getfaceselection node)
meshop.cloneFaces node #all
for j = 1 to segments do meshop.extrudeFaces node #selection -((outer+inner)/segments) 0.0 dir:#independent
outFaces = getfaceselection node
edgeFaces = node.faces as bitarray - inFaces - outFaces
meshop.flipNormals node (outFaces+edgeFaces)
meshop.weldVertsByThreshold node (meshop.getvertsusingedge node (meshop.getopenedges node)) 0.0001
if inMat != unsupplied do for j in inFaces do setFaceMatID node j inMat
if outMat != unsupplied do for j in outFaces do setFaceMatID node j outMat
if edgeMat != unsupplied do for j in edgeFaces do setFaceMatID node j edgeMat
update $
)
ShellMesh $ inner:5.0 outer:15.0 segments:2 inMat:2 outMat:3 edgeMat:4
)
Edit: Welded vertices are wrong, it should be done by element.
Ok, so what you want is to improve the Shell Modifier rather than mimic it right?
If I understand you correctly what you want is to extrude the faces along the same normal when 2 open edges of 2 different elements have their vertices in the same position.
There are several ways to find the average normal of the vertices and then use something like this to do a custom extrude. What I can’t figure out is how to do it in 1 or 2 lines of code if that is what you mean by “how simple it is”.
for j in verts do
(
vpos = getvert node j + ((getnormal node j) * -outer)
setvert node j vpos
)
i definitely want to improve several modifiers – slice, cap_holes, extrude, and shell for sure.
working on “voronoi” task i found that all these modifiers try to make a job using abstract information where they can use absolutely specified.
there is no 100% correct solution to cap holes if you don’t know is loop “inner” or “outer”.
but when you slice a mesh you exactly know the type of made loops.
the max system needs modifiers – slice_and_cap, cut_and_shell, etc. where ‘intersection’ data passes to next option.
I found about the same things while working on the Voronoi Thread.
I was aware of some of the limitations, but I never really cared.
Slice should definitely have an option to cap, and the PolyOp version should have also the options of the Meshop version, remove top, bottom, etc.
The Cap modifier, alone without knowing the sliced data, would be a little tricky to implement, or perhaps impossible in some cases, as the topological data is unknown, but if you sliced the mesh you know all the data.
I find the Shell modifier also a little tricky for what you want to do, which if I am not wrong would be something like what I’ve described above, but could definitely have an option to handle overlapped open edges, or by Smoothing Group or Mat ID, or something that tells what normals should average in order to extrude the faces.
BTW, how simple is the solution you found? Is it a matter of a few lines of code or simple logic what you wanted to say?
Don’t put the solution just yet.
For the Cap problem, one quick and dirty workaround, for example for a sliced tube, could be to build a shape from the open edges, convert to mesh, attach and weld it to the object. It works most of the times, but with some geometries it fails. All the math can be done in the code, but this way is easier.
everything below is exactly the same as i got.
every next step – cap after slice, extrude after slice, etc. happen when the result of ‘cut-slice’ already wiped.
the shell modifier is ridiculously simple. which fact was surprised me. it’s about 3-4 mxs lines of code.
the same story is about extrude, slice, etc.
all of them are from 90th. twenty years old!
how does extrude face (or edge) works? they move in direction on a specified face’s normal.
that’s why we have ‘overlapping’ of shells.
but if every edge will go in direction of verts which are making the edge the extrusion might be better.
Isn’t it something similar to what I said?
As open edges (vertices) have a normal pointing in the direction of the face normal, we have to find the average normal of the two vertices in order to extrude them.
Is that the solution you found?
I am intrigued because you said it was very simple. While finding the average normal isn’t hard to do, I though you found a way to do it in 1 or 2 lines.
it’s not two lines. sorry for disappointing you… but i new that you would be intrigued
that was a point of my ‘trolling’
as i said we have to keep original vert’s normals before cut an use them for ‘per vert’ extrusion.
there is a solution on this forum how to bake and release normals using a map channel.
and i’m ok to show its c++ sdk implementation as a mxs extension (because 80% of it is already shown in the ‘useful mxs extensions’ thread by Klvnk and me).
so we don’t need ‘post-process’ averaging… we have to use ‘pre-process’ data