Ciao
Problema interessante, viene voglia di fare un tentativo …
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:
Superfici nuove:
Superfici disegnate dallo script:
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()