Select to view content in your preferred language

when using setback operations the index of the edges changes in a unpredictable manner

1366
5
04-05-2023 07:20 AM
Mateo_Neira
Emerging Contributor

 

I'm using setbackPerEdge to perform setback operations using a array. I use the edge indices from comp(fe){all: comp.index} to perform different operations dependent on the index I get back, which requires the indices of edges to not change, or change in a predictable manner. 

When I use the setbackPerEdge after having used a shapeO (or setback operation to get the same result)  the new leaf shape has it's edge indices permutated compared to the origin: here is an example where I have a rectangular shape as an initial shape(left) and as we go from left to right we first create an ) shape, then we apply setbackPerEdge a certain number of times as seen in the image bellow:

Mateo_Neira_0-1680698534617.png

at each point I'm translating the shape and visualizing the edge indices of the new shape. As can be seen, the first application of shapeO maintains the edge index order - while adding the new ones at the centre. as soon as we start applying setBackPerEdge to this new shape the edge indices start to shift 0->1, 1->2, and so on.

If we do the same operations on a slightly different initial shape the indices shift in a different way as shown below, where 0->2 and then 2->0 in an alternating way

Mateo_Neira_0-1680706281831.png

 



how do I maintain the indices consistant or keep record of how they change in a predictable manner so I can use them reliably?

The code to reproduce the example is shown bellow:

---

 

 

 

version "2022.1"
import Text:"/ESRI.lib/rules/General/Text.cga"

attr setbackArray = [0,0,2,1] #organized as [front, right, back, left]
attr originalNumEdges = size(edgeLabels)
edgeLabels = comp(fe) { street.front : 0 | street.right: 1 | street.left: 3 | street.back:2 } # to identify index used to query setbackArray for each edge
_edges = size(edgeLabels)


attr floorPlate = 12
@StartRule
plot-->
viewIndex(_edges, edgeLabels)
endShape
setback(
comp(fe){
street.front: floorPlate + setbackArray[0] |
street.right: floorPlate + setbackArray[1] |
street.back: floorPlate + setbackArray[2] |
street.left: floorPlate + setbackArray[3]
}
)
{
all= _footprint(_edges, edgeLabels) |
remainder: NIL
}

_footprint(numEdges, currentEdgeLabels)-->
print(numEdges)
t(50,0,0)
viewIndex(_edges, edgeLabels)
endShape
setback1(_edges, edgeLabels)

setback1(numEdges, currentEdgeLabels)-->
t(50,0,0)
print(_edges)
setbackPerEdge(setbackArray[currentEdgeLabels[comp.index]]){
all= NIL
|remainder:
viewIndex(_edges, edgeLabels)
endShape
setback2(0)
}

setback2(i)-->
case i>3:
NIL
else:
t(50,0,0)
setbackPerEdge( 0 ){
all= NIL
|remainder:
viewIndex(_edges, edgeLabels)
endShape
setback2(i+1)
}



viewIndex(numEdges, currentEdgeLabels)-->
comp(fe)
{
all:
[
case comp.index<originalNumEdges:
case currentEdgeLabels[comp.index] == 0:
# t(5, 0,0)
Text.Letters(comp.index + "- street front",1.5)
else:
# t(5, 0, 0)
Text.Letters("" + comp.index,1.5)
else:
NIL
]
}

endShape -->
color(0.8,0.8,0.8)
endShape.

 

 

0 Kudos
5 Replies
MartinManzer
Esri Contributor

Hi @Mateo_Neira 

Unfortunately this is a bug: A setback operation will change the edge indices in an unpredictable manner. This only happens on shapes with holes as it is the case after your first setback operation. We added this issue to our backlog. Thank you for reporting!

Setbacks on shapes without holes do no change the edge indices.

Selectors (for example street selectors) are not affected and can be used to assign distances or perform a mapping to an array (like you do).

Best,
Martin

0 Kudos
Mateo_Neira
Emerging Contributor

Hi Martin, 

thanks for the response, is there any work around so that I can keep track of different edge indices in those cases? - In a lot of instances I have more than one street facing edge, so the selectors do not provide enough information so I can interact with the leaf shape accordingly. 

0 Kudos
MartinManzer
Esri Contributor

Hi @Mateo_Neira 

The only way I can think of is to add edge indices as edge attributes on the initial shape and reconstruct them using edge attribute functions after the setback. 

However, this requires a manual pre-process for adding edge attributes. Also note that setbacks usually change the topology (for example the outline could be reduced to 3 edges instead of 4 as a result of the setback) such that there might not be 1:1 mapping to the original edge indices.

Can you elaborate more on why you need to have a connection to the original edge indices? Maybe there is a different approach to your problem. Your example code only focuses on applying different distances to different selectors which is still possible.

Best,
Martin

0 Kudos
Mateo_Neira
Emerging Contributor

Hi Martin, 

I'll take a look at the edge attribute function to see if that can do the trick. 

What I'm currently using this for is to be able to setback specific portions of the street facing edges so that the resulting shape will have 35% of the original edge and the rest with a specific setback. The way I'm doing it now is by using recursive rule that uses the splitAndSetbackPerimeter. I recurse through each street front edge and and apply the setback operation only on that edge and then move on to the next one. Bellow is a code example of the use of the splitAndSetbackPerimeter where I create a masked array to select the current edge and apply the setback and recurse to the next edge until all front edges are setback.

	splitAndSetbackPerimeter(0, 0,  currentEdgeMask(_edgeIndex))
		{	startOffset: sb: NIL
			|0.35 * frontFacadeLength(i): 0: NIL
			|~1:sb: NIL
		}
		{remainder: setbackRecursive(
				i+1, 
				frontEdges[i+1]+indexOffset #this indexOffset is how much the original index changes given the setback applied
			)
		}


The result of this rule can be seen bellow, where I'm outputting each step through the recursion:

Mateo_Neira_0-1681233033944.png

In this case the indices change consistently, and I only need to handle the special case of when the setback is applied to an edge which has an index of 0, where if the setback operation happens anywhere other then the start, the edge that stays flush to the streetfront will be indexed at 0 (as can be seen in the image).

Now I wanted to create a hole inside the shape before running the procedure and that is when I ran into the issue of the inconsistency in edge indexing. 

kind regards, 

Mateo

0 Kudos
MartinManzer
Esri Contributor

Thanks @Mateo_Neira ,

I see, tricky problem. I do not have a solution for you but 2 different approaches that are maybe worth to try out:

  • You could use your recursion to only split the perimeter first, i.e. using splitAndSetbackPerimeter with a setback distance of 0. Such that each edge is split at 35% of its length. Secondly, insert a hole. And finally, setback only even (or odd) edges.
  • You could perform splitAndSetbackPerimeter only once on all edges (without recursion) using absolute distances that you pre-compute beforehand. However, then you will need to write separate splitAndSetbackPerimeter statements, each one written for a different number of edges.

Best,
Martin

0 Kudos