Mesh faces , dati i vertici

Sto pasticciando con python , anche con rhino common, ma non sono ancora abilissimo e come al solito ricorro al forum:
Questo il mio caso:

ho preso una mesh ,ne ho estratto degli elementi elementi, in particolare i vertici

from Rhino.Input.Custom import *
from Rhino.DocObjects import ObjectType
from Rhino.Geometry import *
from Rhino.Commands import Result
from scriptcontext import doc as dc
import rhinoscriptsyntax as rs
import Rhino
import Rhino.Geometry as rg
import math
import System.Drawing.Color as rcol
import time
import System

gm=GetObject()
gm.SetCommandPrompt("Select solid meshes ")
gm.GeometryFilter = ObjectType.Mesh
gm.GetMultiple(1, 0)
if gm.CommandResult() != Result.Success:
print gm.CommandResult()
for obj_ref in gm.Objects():
if obj_ref.Mesh() != None:
m=obj_ref.Mesh()
normals2=rs.MeshVertexNormals(obj_ref)
faces = rs.MeshFaces(obj_ref, False)
C_faceVerts = rs.MeshFaceVertices(obj_ref) #lista di tuple: contiene gli indici dei vertici di tutte le facce della mesh.
vertices=m.Vertices # lista di pt3d

dopo una serie di operazioni ho ottenuto una nuova lista L che contiene un numero ridotto di vertici.

il mio problema e’ questo:

come faccio a creare una mesh utilizzando solo le facce che hanno uno, o tutti i vertici nella lista L ?

un caro saluto

franco

Ciao Franco

questa lista contiene i Point3d, non gli indici, e’ cosi’ ?

Il problema e’ passare dai Point3d agli indici ?

Ciao Emilio,

la lista dei vertici contiene gli indici , la ottengo cosi:

L=[]
n=0
per ogni vertice v in vertices:
se v rispetta una certa condizione
L.append(n)
n=n+1

Questi vertici di una mesh sono per me interessanti (ad esempio la normale locale ha una certa direzione).
vorrei ottenere una nuova mesh costituita dalle facce che condividono almeno 1 ( o 2 o3 o 4) di questi vertici.

ho visto che nel Common esistono metodi per ottenere gli indici dei vertici di ogni singola faccia,
ma se ci metto le mani temo di fare come un gatto con un gomitolo.

Vorrei usare solo il Common e non Rhinoscript: l’obiettivo finale e’ avere uno script che possa funzionare senza aprire rhino. Questo mi permetterebbe di leggere un STL, filtrarlo, estrarre la mesh che mi serve e salvarla in un altro stl senza per forza aprire un documento e fare selezioni a mano. Non so se puo’ fare. Cosa ne pensi?

ciao
franco

Ciao Franco
Hmmmm … non credo che si possa usare RhinoCommon al difuori di Rhino.
E in ogni caso se puoi usare RhinoCommon, puoi usare anche rhinoscriptsyntax, che e’ a sua volta una libreria di funzioni che usa RhinoCommon.
Comunque secondo me il modo piu’ semplice e’ fare un ciclo sulle facce della mesh originale
e quando almeno uno dei loro vertici appartiene alla lista che hai costruito, disegnare una mesh a faccia singola.
E alla fine unire le nuove mesh in un’unica mesh.

qui c’e’ il mio tentativo.
Ho usato rhinoscriptsyntax per fare in fretta.
Se ti vuoi vedere il codice RhinoCommon, apri i file della libreria RhinoCommon e ci trovi il codice delle varie funzioni rhinoscriptsyntax.
( Su questo PC ce l’ho in:
C:\Users\Pc\AppData\Roaming\McNeel\Rhinoceros\5.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript )

import rhinoscriptsyntax as rs
  
def main():
  rs.CurrentLayer( rs.AddLayer( 'mesh_1' ) or 'mesh_1' )
  rs.Command( '_MeshSphere 0,0,0 100' )
  mesh_id = rs.FirstObject()
  # esempio di lista con indici dei vertici selezionati
  selindex = [ 6, 7, 8, 9, 12, 13, 14, 15 ]
  indfaces = rs.MeshFaceVertices( mesh_id )
  vertices = rs.MeshVertices( mesh_id )
  rs.CurrentLayer( rs.AddLayer( 'mesh_2' ) or 'mesh_2' )
  newmesh = []
  for indface in indfaces:
    if [ ind for ind in indface if ind in selindex ]:
      newmesh.append( rs.AddMesh( 
            [ vertices[ indface[ 0 ] ], 
              vertices[ indface[ 1 ] ],
              vertices[ indface[ 2 ] ], 
              vertices[ indface[ 3 ] ] ],
            [ [ 0, 1, 2, 3 ] ] ) )
  rs.JoinMeshes( newmesh, True )

main()  

Ciao !

grazie Emilio,

lasciami qualche giorno per approfondire la questione , poi ti aggiornero’

intanto un cordiale saluto

franco

Riciao.
Ho notato che esiste anche rs.MeshVertexFaces() , che ti da’ la lista delle facce che usano un certo vertice.
Forse usando questa funzione la cosa diventa piu’ semplice.
Penso basti inserire in un set gli elenchi delle facce restituite da rs.HeshVertexFaces(), richiamato per ognuno dei vertici selezionati.
Otterremo l’elenco delle facce che costituiscono la nuova mesh.
Ciao

Ciao Emilio,

ho studiato un po’ la faccenda e poi ho scoperto che sul sito di rhino , nella zona svilippatori, c’e un ottimo esempio “AddMesh” : e’ addiritura banale

Si fa una Rhino.Geometry.Mesh(),
gli si appendono le coordinate x,y, dei vertici
gli si appendono i vertex index delle faccette:

ecco qua l’esempio:

import Rhino
import scriptcontext
import System.Guid

def AddMesh():
mesh = Rhino.Geometry.Mesh()
mesh.Vertices.Add(0.0, 0.0, 1.0) #0
mesh.Vertices.Add(1.0, 0.0, 1.0) #1
mesh.Vertices.Add(2.0, 0.0, 1.0) #2
mesh.Vertices.Add(3.0, 0.0, 0.0) #3
mesh.Vertices.Add(0.0, 1.0, 1.0) #4
mesh.Vertices.Add(1.0, 1.0, 2.0) #5
mesh.Vertices.Add(2.0, 1.0, 1.0) #6
mesh.Vertices.Add(3.0, 1.0, 0.0) #7
mesh.Vertices.Add(0.0, 2.0, 1.0) #8
mesh.Vertices.Add(1.0, 2.0, 1.0) #9
mesh.Vertices.Add(2.0, 2.0, 1.0) #10
mesh.Vertices.Add(3.0, 2.0, 1.0) #11

mesh.Faces.AddFace(0, 1, 5, 4)
mesh.Faces.AddFace(1, 2, 6, 5)
mesh.Faces.AddFace(2, 3, 7, 6)
mesh.Faces.AddFace(4, 5, 9, 8)
mesh.Faces.AddFace(5, 6, 10, 9)
mesh.Faces.AddFace(6, 7, 11, 10)
mesh.Normals.ComputeNormals()
mesh.Compact()
if scriptcontext.doc.Objects.AddMesh(mesh)!=System.Guid.Empty:
    scriptcontext.doc.Views.Redraw()
    return Rhino.Commands.Result.Success
return Rhino.Commands.Result.Failure

if name==“main”:
AddMesh()

Grazie di tutto , ( ma fra 5 minuti ne imposto un’altra )

ciao
franco