Notifications
Clear all

[Closed] face replacement with geometry?

Does something like this exist?
I need to have buildings in city scene and for middle distance I woud like to have procedural but controlabe ones. I thinking about creating volume geometry with even distributed faces. and replace faces with facade blocks. Does something like this exist?

something like :
for object 1 take number of faces and clone object 2 for every face.

8 Replies

Hi Stephan,

If i’ve understood this correctly, you are wanting to replace the faces of some proxy geometry with blocks representing objects with more detail, like windows etc?
This is certainly possible with script, you could align the objects with a bit of matrixy stuff.

However, more simply, could this generation not be controlled with a substitute modifier or PFLOW? you could script the ‘states’ of the buildings then to control their appearance.

If you wanted to fully script the geometry creation and/or alignment then you could probably build a matrix from the face normal vector and align the facade pieces with that.

Sorry, this is a work of non scripter :


    A=Box lengthsegs:20 widthsegs:20 heightsegs:20 length:200 width:200 height:200 mapcoords:on pos:[0,0,0]
    A.name = "Box01"
    B=Box lengthsegs:5 widthsegs:5 heightsegs:1 length:20 width:20 height:1 mapcoords:on pos:[0,0,0]
    B.name = "Box02"
    
    Bpos = b.center
    Bwidth = (B.max.x - B.min.x)
    Blenght = (B.max.y - B.min.y)
    Bheight = (B.max.z - B.min.z)
    --Create points
    D01=point()
    D02=point()
    D03=point()
    D04=point()
    D01.pos=[ (Bpos.x + Bwidth / 2), (Bpos.y + Blenght / 2) , (Bpos.z) ]
    D02.pos=[ (Bpos.x + Bwidth / 2), (Bpos.y - Blenght / 2) , (Bpos.z) ]
    D03.pos=[ (Bpos.x - Bwidth / 2), (Bpos.y + Blenght / 2) , (Bpos.z) ]
    D04.pos=[ (Bpos.x - Bwidth / 2), (Bpos.y - Blenght / 2) , (Bpos.z) ]
    --Create FFD
    D = SpaceFFDBox()
    D.width = Bwidth
    D.length = Blenght
    D.height = Bheight
    D.pos=Bpos
    D.tension=25
    select D
    modPanel.addModToSelection (Skin ()) ui:on
    skinOps.addBone D.modifiers[#Skin] D01 1
    skinOps.addBone D.modifiers[#Skin] D02 1
    skinOps.addBone D.modifiers[#Skin] D03 1
    skinOps.addBone D.modifiers[#Skin] D04 1
    D.modifiers[#Skin].bone_Limit = 1
    
    bindSpaceWarp B D
Then I change numbers of points in FFDBox by hand. I did not found way to make it by script. And:
D01= $Point01
    D02= $Point02
    D03= $Point03
    D04= $Point04
    A =$Box01
    
    D01.position.controller = Attachment()
    D01.position.controller.node = A
    addNewKey D01.position.controller 0
    theAKey = AttachCtrl.getKey D01.position.controller 1
    theAKey.face = 1773
    theAKey.coord = [0,0]
    
    D02.position.controller = Attachment()
    D02.position.controller.node = A
    addNewKey D02.position.controller 0
    theAKey = AttachCtrl.getKey D02.position.controller 1
    theAKey.face = 1773
    theAKey.coord = [0,1]
    
    D03.position.controller = Attachment()
    D03.position.controller.node = A
    addNewKey D03.position.controller 0
    theAKey = AttachCtrl.getKey D03.position.controller 1
    theAKey.face = 1773
    theAKey.coord = [1,-1]
    
    D04.position.controller = Attachment()
    D04.position.controller.node = A
    addNewKey D04.position.controller 0
    theAKey = AttachCtrl.getKey D04.position.controller 1
    theAKey.face = 1773
    theAKey.coord = [1,0]
    
The real hard part is before me.How to copy it. Thanks for your answer but as U can see I am no scripter so "bulid matrix" is realy not in my vocabulary Sorry :)

I am trying to set keyes for attatchment with script but it ends around face 2400. Am I doing something wrong?


  ObjA=$Box01
  ObjB=$line01
  
  --A operations
  addModifier ObjA (FFD_2x2x2())
  ObjAFFD=OBJA.modifiers[#FFD_2x2x2]
  animateVertex ObjAFFD #all
  boxMin = getModContextBBoxMin ObjA ObjAFFD
  boxLen = (getModContextBBoxMax OBJA ObjAFFD) - boxmin
  ArrayFFDpos = #( [0,0,0] , [0,0,0] , [0,0,0] , [0,0,0] )
  
  --B operations
  addModifier ObjB (push())
  maxOps.cloneNodes ObjB cloneType:#copy newNodes:&nnl
  maxOps.cloneNodes ObjB cloneType:#copy newNodes:&nnl
  ObjBinside=nnl[1]
  ObjBoutside=nnk[1]
  ObjBinside.modifiers[#Push].Push_Value = ObjA.min.z
  ObjBoutside.modifiers[#Push].Push_Value = ObjA.max.z
  	
  maxOps.CollapseNodeTo ObjBinside 1 on
  maxOps.CollapseNodeTo ObjBoutside 1 on
  
  
  FacesB = ObjB.EditablePoly.getSelection #face as array
  ObjTrans = ObjB.objectTransform.translationpart
  --Nepar=#(1,3,5,7)
  --Par=#(2,4,6,8)
  
  For j = 1 to FacesB.count do
  (
   A = polyop.getFaceVerts ObjB FacesB[j]
  	for i = 1 to 4 do
  	( 
  	LocalB = ObjBoutside.GetVertex A[i] --get local vertex position for face selection
  	B = ObjTrans+LocalB   --and make it global
  	LocPoint  = B * (inverse ObjA.transform)  --make it local to ffdobject
  	FFDPoint = (LocPoint - boxMin) / boxLen  --normalize
  	insertItem FFDPoint ArrayFFDpos i
  	deleteitem FFDPoint 5
  		
  	ObjAFFD.control_point_2 = ArrayFFDpos[1]
  	ObjAFFD.control_point_4 = ArrayFFDpos[4]
  	ObjAFFD.control_point_6 = ArrayFFDpos[2]
  	ObjAFFD.control_point_8 = ArrayFFDpos[3]
  	)
  		for i = 1 to 4 do
  	( 
  	LocalB = ObjBinside.GetVertex A[i] --get local vertex position for face selection
  	B = ObjTrans+LocalB   --and make it global
  	LocPoint  = B * (inverse ObjA.transform)  --make it local to ffdobject
  	FFDPoint = (LocPoint - boxMin) / boxLen  --normalize
  	insertItem FFDPoint ArrayFFDpos 
  	deleteitem FFDPoint 5
  		
  	ObjAFFD.control_point_1 = ArrayFFDpos[1]
  	ObjAFFD.control_point_3 = ArrayFFDpos[4]
  	ObjAFFD.control_point_5 = ArrayFFDpos[2]
  	ObjAFFD.control_point_7 = ArrayFFDpos[3]
  	)
  	
  )

There is still no copy. And big part will not work, but this is a way I go.it is mix of 3 or 5 scripts, so.:shrug:


 ObjA=$Box01
 ObjB=$Plane01
 FacesB = ObjB.getSelection #Face as bitarray
 
 --A operations
 addModifier ObjA (FFD_2x2x2())
 ObjAFFD=OBJA.modifiers[#FFD_2x2x2]
 animateVertex ObjAFFD #all
 boxMin = getModContextBBoxMin ObjA ObjAFFD
 boxLen = (getModContextBBoxMax OBJA ObjAFFD) - boxmin
 ArrayFFDpos = #( [0,0,0] , [0,0,0] , [0,0,0] , [0,0,0] )
 
 --B operations
 addModifier ObjB (push())
 addModifier ObjB (Edit_Poly ())
 maxOps.cloneNodes ObjB cloneType:#copy newNodes:&nnl
 maxOps.cloneNodes ObjB cloneType:#copy newNodes:&nnk
 ObjBinside=nnl[1]
 ObjBoutside=nnk[1]
 ObjBinside.modifiers[#Push].Push_Value = ObjA.min.z
 ObjBoutside.modifiers[#Push].Push_Value = ObjA.max.z
 
 maxOps.CollapseNodeTo ObjBinside 1 on
 maxOps.CollapseNodeTo ObjBoutside 1 on
 maxOps.CollapseNodeTo ObjB 1 on
 
 
 SelectionB = ObjB.setSelection #Face FacesB
 ObjTrans = ObjB.objectTransform.translationpart
 
 FacesB = ObjB.getSelection #Face as array
 for j = 1 to FacesB.count do
 (
 ObjAj=copy ObjA
 vertB = polyop.getFaceVerts ObjB FacesB[j]
 
 for i = 1 to 4 do --outside
 ( 
 LocalB = ObjBoutside.GetVertex vertB[i] --get local vertex position for face selection
 B = ObjTrans+LocalB   --and make it global
 LocPoint  = B * (inverse ObjA.transform)  --make it local to ffdobject
 FFDPoint = (LocPoint - boxMin) / boxLen  --normalize
 insertItem FFDPoint ArrayFFDpos i
 deleteitem ArrayFFDpos 5
 
 		
 	objAJ.modifiers[#FFD_2x2x2].control_point_2 = ArrayFFDpos[1]
 	objAJ.modifiers[#FFD_2x2x2].control_point_4 = ArrayFFDpos[4]
 	objAJ.modifiers[#FFD_2x2x2].control_point_6 = ArrayFFDpos[2]
 	objAJ.modifiers[#FFD_2x2x2].control_point_8 = ArrayFFDpos[3]
 	)
 for i = 1 to 4 do --inside
 ( 
 LocalB = ObjBinside.GetVertex vertB[i] --get local vertex position for face selection
 B = ObjTrans+LocalB   --and make it global
 LocPoint  = B * (inverse ObjA.transform)  --make it local to ffdobject
 FFDPoint = (LocPoint - boxMin) / boxLen  --normalize
 insertItem FFDPoint ArrayFFDpos i
 deleteitem ArrayFFDpos 5
 
 		
 	objAJ.modifiers[#FFD_2x2x2].control_point_1 = ArrayFFDpos[1]
 	objAJ.modifiers[#FFD_2x2x2].control_point_3 = ArrayFFDpos[4]
 	objAJ.modifiers[#FFD_2x2x2].control_point_5 = ArrayFFDpos[2]
 	objAJ.modifiers[#FFD_2x2x2].control_point_7 = ArrayFFDpos[3]
 	)
 
 )
 
 delete ObjBinside
 delete ObjBoutside
 
 

And thanks all for help

Could someone help me please. the script in prew post works I am trying to do rollout with pick buttons. But then the script does not work. Where I am doing something wrong?

rollout Proc "ProcBuild" width:216 height:256
 (
 	button btn1 "DoIt!" pos:[45,179] width:118 height:48
 	pickButton btn2 "Block" pos:[29,59] width:155 height:32
 	pickButton btn3 "building" pos:[29,114] width:152 height:38
 	on btn2 picked Li do
 	ObjA=Li
 	on btn3 picked La do
 	ObjB=La
  on btn1 pressed do
 (
 --ObjA=btn2 picked
 --ObjB=btn3 picked
 FacesB = ObjB.getSelection #Face as bitarray
 
 --A operations
 addModifier ObjA (FFD_2x2x2())
 ObjAFFD=OBJA.modifiers[#FFD_2x2x2]
 animateVertex ObjAFFD #all
 boxMin = getModContextBBoxMin ObjA ObjAFFD
 boxLen = (getModContextBBoxMax OBJA ObjAFFD) - boxmin
 ArrayFFDpos = #( [0,0,0] , [0,0,0] , [0,0,0] , [0,0,0] )
 
 --B operations
 addModifier ObjB (push())
 addModifier ObjB (Edit_Poly ())
 maxOps.cloneNodes ObjB cloneType:#copy newNodes:&nnl
 maxOps.cloneNodes ObjB cloneType:#copy newNodes:&nnk
 ObjBinside=nnl[1]
 ObjBoutside=nnk[1]
 ObjBinside.modifiers[#Push].Push_Value = ObjA.min.z
 ObjBoutside.modifiers[#Push].Push_Value = ObjA.max.z
 
 maxOps.CollapseNodeTo ObjBinside 1 on
 maxOps.CollapseNodeTo ObjBoutside 1 on
 maxOps.CollapseNodeTo ObjB 1 on
 
 
 SelectionB = ObjB.setSelection #Face FacesB
 ObjTrans = ObjB.objectTransform.translationpart
 
 FacesB = ObjB.getSelection #Face as array
 for j = 1 to FacesB.count do
 (
 ObjAj=copy ObjA
 vertB = polyop.getFaceVerts ObjB FacesB[j]
 
 for i = 1 to 4 do --outside
 ( 
 LocalB = ObjBoutside.GetVertex vertB[i] --get local vertex position for face selection
 B = ObjTrans+LocalB   --and make it global
 LocPoint  = B * (inverse ObjA.transform)  --make it local to ffdobject
 FFDPoint = (LocPoint - boxMin) / boxLen  --normalize
 insertItem FFDPoint ArrayFFDpos i
 deleteitem ArrayFFDpos 5
 
 		
 	objAJ.modifiers[#FFD_2x2x2].control_point_2 = ArrayFFDpos[1]
 	objAJ.modifiers[#FFD_2x2x2].control_point_4 = ArrayFFDpos[4]
 	objAJ.modifiers[#FFD_2x2x2].control_point_6 = ArrayFFDpos[2]
 	objAJ.modifiers[#FFD_2x2x2].control_point_8 = ArrayFFDpos[3]
 	)
 for i = 1 to 4 do --inside
 ( 
 LocalB = ObjBinside.GetVertex vertB[i] --get local vertex position for face selection
 B = ObjTrans+LocalB   --and make it global
 LocPoint  = B * (inverse ObjA.transform)  --make it local to ffdobject
 FFDPoint = (LocPoint - boxMin) / boxLen  --normalize
 insertItem FFDPoint ArrayFFDpos i
 deleteitem ArrayFFDpos 5
 
 		
 	objAJ.modifiers[#FFD_2x2x2].control_point_1 = ArrayFFDpos[1]
 	objAJ.modifiers[#FFD_2x2x2].control_point_3 = ArrayFFDpos[4]
 	objAJ.modifiers[#FFD_2x2x2].control_point_5 = ArrayFFDpos[2]
 	objAJ.modifiers[#FFD_2x2x2].control_point_7 = ArrayFFDpos[3]
 	)
 
 )
 
 delete ObjBinside
 delete ObjBoutside
 
 	)
 )
 createDialog Proc 200 300 300 200
 

Would it be possible to put somewhere “ArrayFFDpos after i loop” to “copy of ObjA” for later use? Sometimes the orientation of created and moddified objects is not right So it would be great to have possibility for change it. If “ArrayFFDpos after i loop” woud be saved on per object basys I could just scroll through. How would You approach it?

So it is something like tool. It replaces ObjB facess with ObjA with help of FFD 2x2x2. ObjA has to be created from top window or need ResetXForm. And all faces in ObjB need to be quadrangles.

I am just sending some script




ExtrMin = 10
ExtrMax = 200
Num = ExtrMax - ExtrMin
A=selection as array



For j = 1 to A.count do 

(
ObB = A[j]
V=ObB.verts
ColZ=[0, 0, 0]

For i = 1 to V.count do
(
colV=getVertColor ObB i as point3
ColZ2=ColZ+ColV
ColZ=ColZ2
)
ColFac = ColZ / V.count
NumFac = (ColFac[1]+ColFac[2]+ColFac[3])/765
Extr = Num * NumFac + ExtrMin
select ObB
modPanel.addModToSelection (Shell ())
ObB.modifiers[#Shell].outerAmount = Extr
maxOps.CollapseNode ObB on
)