Definizione x comparazione oggetti

ciao a tutti,
concorso aperto a tutti i volenterosi smanettoni (per vedere se rhino e GH riescono a pareggiare una funzione di altri software (NX))

dato di partenza: ho due file contenenti un medesimo assieme in cui il secondo è un aggiornamento del primo;
non ho indicazioni, nè di testo nè di modellazione (es. colore…) che mi evidenzino cosa e dove siano i cambiamenti/aggiornamenti delle geometrie tra il primo file e il secondo;

wish:
comando script oppure definizione GH che mi faccia selezionare SOLO due geometrie delle due release (che avrò già importato in un unico file) e compararle;
la comparazione dovrebbe evidenziare le superfici uguali con un colore (azzurro), le superfici modificate con un altro (giallo) e le suferfici nuove con un altro ancora (rosso)

(per superfici modificate intendo superfici che hanno solo subito cambiamenti di trimmatura)

ps se venisse in mente anche un quarto colore per evidenziare un’altra caratteristica va benissimo :clock9:

grazie a tutti i volenterosi

Questa definizione confronta due file.
Nulla vieta che siano caricati in Rhino.
È abbastanza semplice, basta specificare il percorso della cartella che contiene i file e il nome dei file stessi.
Come si vede verifica solo se ci sono superfici differenti e non tiene conto dell’eventuale spostamento delle stesse.
Non rileva nuove superfici, anzi, se ci sono nuove superfici non dovrebbe funzionare.

1 Mi Piace

segnale link sul forum americano

Ciao

Problema interessante, viene voglia di fare un tentativo … :slight_smile:

Qui c’e’ uno script in IronPython, provato su Rhino 6, semplificato al massimo.

Bisogna preselezionare le superfici vecchie
Poi si lancia lo script
Si selezionano le superfici nuove
Lo script chiede la tolleranza
Poi chiede il passo per la verifica dei bordi
Chiede ancora se deve cancellare le superfici nuove, dato che le ridisegna colorate

Lo script controlla la posizione dei CV per le superfici.
Mentre per i bordi controlla che i punti ricavati da un bordo si trovino sul bordo di confronto.

Fatta la verifica, disegna delle copie delle superfici nuove con i colori richiesti.

Dato il modo con cui controlla i bordi, se la lunghezza totale dei bordi e’ elevata, puo’ volerci un certo tempo.

Ovviamente ognuno e’ libero di modificare lo script come gli pare.

Usare a proprio rischio e pericolo

Esempio:

Superfici vecchie:
immagine

Superfici nuove:
immagine

Superfici disegnate dallo script:
immagine

import Rhino
import scriptcontext
import System

def samenursurknots( ka, kb, tol ):
  cnt = ka.Count
  if kb.Count != cnt:
    return False
  for ix in range( cnt ):
    if abs( ka[ ix ] - kb[ ix ] ) > tol:
      return False
  return True

def samenursurcvs( pa, pb, tol ):
  cntu = pa.CountU
  cntv = pa.CountV
  if pb.CountU != cntu:
    return False
  if pb.CountV != cntv:
    return False
  for ix in range( cntu ):
    for jx in range( cntv ):
      cva = pa.GetControlPoint( ix, jx )
      cvb = pb.GetControlPoint( ix, jx )
      if abs( cva.X - cvb.X ) > tol:
        return False
      if abs( cva.Y - cvb.Y ) > tol:
        return False
      if abs( cva.Z - cvb.Z ) > tol:
        return False
      if abs( cva.Weight - cvb.Weight ) > tol:
        return False
  return True

def samecurs( cusa, cusb, tol, stp ):
  for cua in cusa:
    uus = cua.DivideByLength( stp, True )
    for uu in uus:
      pt = cua.PointAt( uu )
      oncrv = False
      for cub in cusb:
        ok, t = cub.ClosestPoint( pt, tol )
        if ok:
          oncrv = True
          break
      if not oncrv:
        return False
  return True

def samebasesur( centa, diaga, nusua, centb, diagb, nusub, tol ):
  if abs( centa.X - centb.X ) > tol:
    return False
  if abs( centa.Y - centb.Y ) > tol:
    return False
  if abs( centa.Z - centb.Z ) > tol:
    return False
  if abs( diaga.X - diagb.X ) > tol:
    return False
  if abs( diaga.Y - diagb.Y ) > tol:
    return False
  if abs( diaga.Z - diagb.Z ) > tol:
    return False
  if not samenursurknots( nusua.KnotsU, nusub.KnotsU, tol ):
    return False
  if not samenursurknots( nusua.KnotsV, nusub.KnotsV, tol ):
    return False
  if not samenursurcvs( nusua.Points, nusub.Points, tol ):
    return False
  return True

def cmpfacelists( facsa, facsb, tol, stp ):
  bbcesa = []
  bbdisa = []
  nususa = []
  curssa = []
  for faca in facsa:
    bb = faca.GetBoundingBox( True )
    bbcesa.append( bb.Center )
    bbdisa.append( bb.Diagonal )
    nususa.append( faca.ToNurbsSurface() )
    rep = faca.DuplicateFace( False )
    curssa.append( list( rep.DuplicateEdgeCurves() ) )
  bbcesb = []
  bbdisb = []
  nususb = []
  curssb = []
  for facb in facsb:
    bb = facb.GetBoundingBox( True )
    bbcesb.append( bb.Center )
    bbdisb.append( bb.Diagonal )
    nususb.append( facb.ToNurbsSurface() )
    rep = facb.DuplicateFace( False )
    curssb.append( list( rep.DuplicateEdgeCurves() ) )
  statea = [ 'nil' ] * len( facsa )
  procdb = [ False ] * len( facsb )
  tot = len( facsa )
  cnt = 0
  for ia in range( len( facsa ) ):
    cnt += 1
    if ( cnt % 10 ) == 0:
      Rhino.RhinoApp.SetCommandPrompt( '%d / %d faces' % ( cnt, tot ) )
    for ib in range( len( facsb ) ):
      if procdb[ ib ]:
        continue
      if not samebasesur( bbcesa[ ia ], bbdisa[ ia ], nususa[ ia ], 
                          bbcesb[ ib ], bbdisb[ ib ], nususb[ ib ], tol ):
        continue
      procdb[ ib ] = True
      if ( samecurs( curssa[ ia ], curssb[ ib ], tol, stp ) and
           samecurs( curssb[ ib ], curssa[ ia ], tol, stp ) ):
        statea[ ia ] = 'rep'
      else:
        statea[ ia ] = 'sur'
      break
  return statea

def rep2faces( rep ):
  cnt = rep.Faces.Count
  faces = []
  for ix in range( cnt ):
    faces.append( rep.Faces[ ix ] )
  return faces

def main():
  robs = list( scriptcontext.doc.Objects.GetSelectedObjects( False, False ) )
  if not robs:
    print( 'Old surfaces have to be preselected ... quitting' )
    return
  facsb = []
  for rob in robs:
    rep = Rhino.DocObjects.ObjRef( rob ).Brep()
    if rep:
      facsb.extend( rep2faces( rep ) )
  scriptcontext.doc.Objects.UnselectAll()
  for rob in robs:
    scriptcontext.doc.Objects.Hide( rob, True )
  scriptcontext.doc.Views.Redraw()
  print( '=> %d old (poly)surfaces' % len( robs ) )
  gob = Rhino.Input.Custom.GetObject()
  gob.SetCommandPrompt( 'Please, select new surfaces' )
  gob.AcceptNothing( True )
  gob.GeometryFilter = Rhino.DocObjects.ObjectType.Brep
  gob.GetMultiple( 0, 0 )
  res = gob.Result()
  if res == Rhino.Input.GetResult.Object:
    obrefs = gob.Objects()
  else:
    return
  print( '=> %d new (poly)surfaces' % len( obrefs ) )
  facsa = []
  for obref in obrefs:
    facsa.extend( rep2faces( obref.Brep() ) )
  print( '=> %d new faces to check' % len( facsa ) )
  tol = 0.1
  res, tol = Rhino.Input.RhinoGet.GetNumber( 'Tolerance ?', True, tol )
  if res != Rhino.Commands.Result.Success:
    return
  stp = 0.5
  res, stp = Rhino.Input.RhinoGet.GetNumber( 
      'Step for borders check ?', True, stp )
  if res != Rhino.Commands.Result.Success:
    return
  dlt = 'N'
  res, dlt = Rhino.Input.RhinoGet.GetString( 
      'Delete new surfaces in document [Y/N] ?', True, dlt )
  if res != Rhino.Commands.Result.Success:
    return
  Rhino.RhinoApp.SetCommandPrompt( ' ' * 120 )
  dlt = dlt[ 0 ].lower()
  states = cmpfacelists( facsa, facsb, tol, stp )
  if dlt == 'y':
    for obref in obrefs:
      scriptcontext.doc.Objects.Delete( obref, True )
  for rob in robs:
    scriptcontext.doc.Objects.Show( rob, True )
  for ix in range( len( facsa ) ):
    if states[ ix ] == 'nil':
      colr = System.Drawing.Color.Red
    elif states[ ix ] == 'sur':
      colr = System.Drawing.Color.Yellow
    elif states[ ix ] == 'rep':
      colr = System.Drawing.Color.Cyan
    else:
      print( 'Error: unexpected state <%s>' % states[ ix ] )
    attr = Rhino.DocObjects.ObjectAttributes()
    attr.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject
    attr.ObjectColor = colr
    attr.LayerIndex = scriptcontext.doc.Layers.CurrentLayerIndex
    scriptcontext.doc.Objects.AddBrep( 
        facsa[ ix ].DuplicateFace( False ), attr )
  scriptcontext.doc.Views.Redraw()

main()
4 Mi Piace