Mesh faces by parent

Hi @DanielPiker or anyone else that is interested,

Is the script shown in the below page still available somewhere?
It seems that the “ByParent” component in Kangaroo is slightly different for it takes an initial mesh, subdivides, and then outputs a tree, but instead I would like to be able to select faces (say, after Weaverbird’s Loop or its other SubD processes) base on their original parent faces (pre-subdivision):

Thanks!

1 Like

I think this is the file I posted there:
WBLoopFacesByParent.gh (8.5 KB)
It’s specific to Loop subdivision, and probably also to Weaverbird, since it uses the particular ordering of the face list.
I did also work a while back on a more general ‘reverse subd’ algorithm to recover base meshes from any Catmull-Clark quad meshes without any specific face ordering, by splitting outwards from the irregular vertices. I’ll dig it out and post it soon.

(also - I didn’t realise that uploaded files were disappearing from the old NING site. That’s going to be a pain)

2 Likes

Thank you very much!

It’s specific to Loop subdivision, and probably also to Weaverbird, since it uses the particular ordering of the face list.

I was hoping this wasn’t the case since a more generalized reverse workflow as you pointed out would be very useful, as I was basically using it to find face loops based on each of the original faces such that you could create “windows” in the mesh - for example, the loops of newly subdivided faces that are topologically further away from the initial naked edges get culled out. These face loops would be a lot easier to be identified if they are divided into branches based on the original faces.

In the meantime, this is how I was doing it in a brute force manner, measuring the closest point from subdivided face centers back to the original mesh prior to subdivision, as subdivision steps increase and as the mesh relaxes, errors begin to occur where some faces get assigned to the wrong branch:


(also - I didn’t realise that uploaded files were disappearing from the old NING site. That’s going to be a pain)

Initially I thought that was the case since it’s obsolete, but it seems like lots of other attachments are still available

Hi @piac

Might there be an approach that works generally for Weaverbird?

Below is a workaround I had by adapting Daniel’s script in the case where I wanted to subdivide the original mesh before the relaxation so to speak (since after the join and weld the indices of the original faces are sort of lost) WBLoopFacesByParent_2.gh (15.1 KB)
:


Hi guys,

the Weaverbird face ordering is grouped from each input, and each subdivision type takes the amount of faces from some property of the original input. The new faces are always created in order. Therefore, in general it’s always possible to go back to understand where the face came from. If you ask which particular component is of your interest, I could tell you the order.

Thanks,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

1 Like

Thank you very much for graciously offering to share the code. It sounds like some of the subdivision processes follow different orders so there’s not a process that would work with all of them? If so, I would mostly be interested in knowing the order of Constant Quad and Catmull-Clark SubD structures/orders within Wb for quad faces are what I’m working with. One relevant question I have when I was testing things out (please refer to the post above your response) was whether the Join and Weld component might change the ordering/indices - sometimes I might want to subdivide and refine the initial faces, join and weld, and then subdivide for relaxation.

Something similar to the below snippet of code for the Mesh from Lines component you shared a while back would be immensely helpful:

import clr
clr.AddReference("Weaverbird.Core")
clr.AddReference("Weaverbird.CommonSdkSupport")

import Weaverbird as wb
import Weaverbird.CommonSupport as wbc
import Rhino as rc
import System as s

L = s.Collections.Generic.List[rc.Geometry.Line](L)

a = wb.WbStatic.WbWeaveBack[s.Array[rc.Geometry.PolylineCurve], wb.Geometry.IPoints.LineCurve](
    wbc.Support.Import(L), V,
    wbc.CommonPolylinesFactory.Instance,
    None, rc.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance)

I was hoping I could do this on my own, but I couldn’t seem to find a documentation of all the properties and functions within Wb to code with.

Could you give an overview of the whole sequence of operations you want to do?
Depending on this I think there might even be a simpler way possible here.
You can use a mesh or multiple meshes in the Show component of Kangaroo, with different vertex and face ordering to some other meshes you use for relaxation, and as long as the vertices coincide they will stay attached.

1 Like

Hi Daniel,

This is a simplified version WBLoopFacesByParent_3.gh (12.4 KB) :
The script requires the mesh+ plugin for now to identify face loops (eventually it’d be nice to have a script component without the plugin…), with quad faces, the tree branch I would extract would be 0, instead of 7 or some other less predictable number because of the triangular faces resulted from the loop subdivision.

I would like to replace the first two loop components with wb’s catmull-clark or other quad subd’s and still be able to identify the parent-child relationship. Essentially, being able to extract the outer face loops based on initial input faces.
Hopefully this is clearer, and thanks again!


I’ll see what Daniel has to add regarding the simpler method.

Regarding the other questions, _Join (in general) does not change the order or faces or vertices, but the faces and vertices from the second, third, etc meshes get added after the ones from the first mesh. _Weld changes the order of vertices, not of faces. This is because coincident vertices get unified.

Catmull-Clark creates a new quad face for ( each face * each edge in that face original ), in this order. This means that after the first subdivision – which will create all quads – , it will always create n quads = 4 * (number of faces) . The first step will create faces = sum of edges in each face.

Regarding the code to run C/C, you can use this simplified method:

import clr
clr.AddReference("Weaverbird.Core")
clr.AddReference("Weaverbird.CommonSdkSupport")

import Weaverbird as wb

wb.Common.Subdivision.CatmullClark(...

Thanks,

Giulio


Giulio Piacentino
for Robert McNeel & Associates
giulio@mcneel.com

1 Like

Thank you Giulio, I will try to develop further with the info you gave.