create chamfer in corner building

3308
8
09-18-2021 12:49 AM
hadiyousefi
New Contributor II

Hi friends - I want to create  chamfer for the corner buildings in the block. When using Attribute Chamfer_Direction, every option I choose creates only a chamfer building. Of course, I also used || and && operators, which do not answer . I want when I select one option, for example, the FR option, when I add another option, the first item, that is, the FR, will also run, as well as for the other options. In fact, I want create chamfer for the corner building same time when I select options in attribute Chamfer_Direction .for example when i select the FR and FL and BR for corner building only create chamfer for these three items as well as for other options whether anyone has a solution for this . my english is not very good, so I hope I have conveyed what I mean. very thanks . Is specified in the attached images

0 Kudos
8 Replies
BrianWamsley
Occasional Contributor III

This is a tricky problem and I am trying to give a quick answer...

It looks like your using a string array for your attribute selector.   To make an array work with a conditional command you'll need a few steps before.   You need to set an indices to make your array output single string/float/bool values.  To do this, you'll have to setup a recursive step to run through your array, typically from 0 to  the size of column total.   Each recursive step then parameterizes an individual array indices for a new step.

But that's not your only challenge.   You'll also need a recursion of some sort to pivot your scope so that it splits the same shape tree and doesn't create a new shape for each corner chamfer cut.   I have done something similar to this before but not with a string array for selecting the attribute.  I'll have to think on that step. 

0 Kudos
hadiyousefi
New Contributor II

hi  Brian .thank you for your answer . how i can set an indices to make my array output single string/float/bool values. how do I do that? as well as using the recursive mode for the array . It is possible to explain more

this is my rule for this section :

@Order(0)@Enum(valuesAttr=ChamferDirection)
attr chamfer_Direction = stringArray()

@Hidden
attr ChamferDirection = ["FR";
"FL";
"BR";
"BL"]

#-----------------------------

What code should be used for my array to output as a single bool/float/string, and also to create a recursive  mode for the array

attr Corner_Trim =false

@Order(0)@Enum(valuesAttr=ChamferDirection)
attr chamfer_Direction = stringArray()


attr Boolian_chamfer_Direction =bool("chamfer_Direction")    or

boolArray(chamfer_Direction) 

// this after added

@Hidden
attr ChamferDirection = ["FR";
"FL";
"BR";
"BL"]

#----------------------------------------------

BlockLot(n) -->

case Split_axis =="X" : // for X split
case n ==1 && chamfer_Direction ==["FR"] :
alignScopeToAxes(y)
rotateScope(0, 180, 180)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }

case n ==2 && chamfer_Direction ==["FL"] :
alignScopeToAxes(y)
rotateScope(0, 0, 0)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }


case n ==3 && chamfer_Direction ==["BR"] :
alignScopeToAxes(y)
rotateScope(0, 180, 0)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }


case n ==4 && chamfer_Direction ==["BL"] :
alignScopeToAxes(y)
rotateScope(180, 0, 180)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }

else :RemaindLand

else : // for Z split
case n ==1 && chamfer_Direction ==["BR"] :
alignScopeToAxes(y)
rotateScope(0, 180, 180)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }

case n ==2 && chamfer_Direction ==["BL"] :
alignScopeToAxes(y)
rotateScope(0, 180, 0)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }


case n ==3 && chamfer_Direction ==["FR"] :
alignScopeToAxes(y)
rotateScope(0, 0, 0)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }


case n ==4 && chamfer_Direction ==["FL"] :
alignScopeToAxes(y)
rotateScope(180, 0, 180)
rotateScope(0,chamfer_Angle, 0)
split(x) { chamfer_Dis : NIL |~1:RemaindLand }

else :RemaindLand

#--------------------------------------------------

very thanks.

0 Kudos
BrianWamsley
Occasional Contributor III

hadiyousefi,

Quick note:  looking at your code, you were turning the string array into a string using the @Enum(valuesAttr=ChamferDirection).  

I took a little different approach to achieve the desired result.  You will see how to use an index/indice for an array in this example.  This code was built without any recursion because it seemed that you were planning on using 4 sided blocks (from your pictures) and I think this makes it easier to show the necessary steps.   Any blocks with more or less than 4 sides and close to 90 degree angles and this code would need to be modified.  Furthermore, to understand this code you just have to remember that each edge has a comp.index number and the Chamfer_Corner gives a chamfer based on true or false (really just true must exist) based on the comp.index number for that edge.

 

 

 

attr Chamfer_Corner = ["True","True","True","True"]

attr chamfer_Dis = 10

@StartRule	
ChamferBlock-->
	extrude(5)
	ChamferBlock1

ChamferBlock1-->
	case Chamfer_Corner[0] == "True":    //index of Chamfer_Corner array at 0
		setPivot(xyz,0)              //index of shape edge with comp.index at "0"
		rotateScope(0,45,0)          //sets the chamfer angle
		split(x){chamfer_Dis: NIL | ~1: ChamferBlock2}
	else:
		setPivot(xyz,0)
		rotateScope(0,45,0) 
		ChamferBlock2	
	
ChamferBlock2-->
	case Chamfer_Corner[1] == "True":
		setPivot(xyz,1)
		split(x){chamfer_Dis: NIL | ~1: ChamferBlock3}
	else: ChamferBlock3		
	
ChamferBlock3-->
	case Chamfer_Corner[2] == "True":
		setPivot(xyz,2)
		split(x){chamfer_Dis: NIL | ~1: ChamferBlock4}
	else: ChamferBlock4				
	
ChamferBlock4-->
	case Chamfer_Corner[3] == "True":
		setPivot(xyz,3)
		split(x){chamfer_Dis: NIL | ~1: BlockEnd}
	else:  
		setPivot(xyz,3)   //just so that Block End has expected behavior either way.
		BlockEnd		

 

 

 

 

0 Kudos
hadiyousefi
New Contributor II

I did not look at it from this perspective. Thank you for your guidance. The only problem is that the Chamfer_Corner attribute options in this case do not change easily to true or false. All you have to do is delete or type the true option

0 Kudos
BrianWamsley
Occasional Contributor III

You can add @Enum("True","False") before attr Chamfer_Corner to create a domain for the table.  

0 Kudos
hadiyousefi
New Contributor II

Thank you dear Brian. Another question. This rule creates chamfer for blocks that are quadrilateral. What should be done for blocks that are like U or L when we want to create chamfer for all sides?

0 Kudos
BrianWamsley
Occasional Contributor III

If you are just talking about the 4 original corners of the square-shaped block, then I think you could still use the "BlockEnd" from the rule, proceeding with a controlled scope that does "splits and NILs" to get an L shaped block or U shaped block. 

However, a rule applied directly to an irregular (n-sided) polygon with obtuse interior angles (U-shape or L-shape) is going to be a very difficult challenge.  The method you are using, manipulating the scopes for trim planes, would not work for more complex shapes.  Interior angles that go within/inside the scope, would need some of kind of scope pivot and shrink that would involve some complicated math.   And if those interior angles are obtuse, you would need to add to the shape, not trim it like what is being done already, so a code for that would have to be figured out.   I have been keeping my eye out to see if someone in CE has a break through on this, but I have not seen it yet.      

Therefore, this is where I would start to consider a shape insert technique (e.g. use the shape modeling tools, or Sketchup, to create the desired floor/block shape) and insert that into your starting area to create "pre-modeled" chamfer cuts.   Perhaps use insertAlongUV to make it fit the scope better.  

 

0 Kudos
hadiyousefi
New Contributor II

Hi Brian, thank you for your answer . This method does not work for L shape or U shape when I use the SetPivot and or Rotate Scope command . This method only works for 4 corners and does not work for the corners inside the block that is U or L. because I do this for the municipality, the municipal employees should only do this within the CityEngine software . I also used the shape insert technique, which used the insertAlongUV command that the block prepared in the OBJ format It was not in the right place. Do you think it is possible to extrtude the sections divided by the insertAlongUV command without using the external model? Like the image below. very thanks

0 Kudos