|
POST
|
The comp operation will categorize faces as front, back, left, right, top, bottom according to the faces' normals in relation to the scope's coordinate system. The following screenshot shows how faces are categorized for a cube with the given scope (xyz axes in red, green, blue). comp operation—CGA | Documentation
... View more
04-22-2020
08:47 AM
|
1
|
0
|
1318
|
|
POST
|
You could try alignScopeToAxes(y) to make sure the scope's y direction matches world.y. alignScopeToAxes operation—CGA | Documentation
... View more
04-22-2020
08:36 AM
|
0
|
0
|
858
|
|
POST
|
You can also find the assets for the goal and ball in the Desert City Example (Help -> Download Tutorials and Examples) in Example_Desert_City__2019_1\assets\soccerField.
... View more
04-22-2020
06:40 AM
|
0
|
0
|
1466
|
|
POST
|
Yes. Start with the initial shape of the parking lot. Do an offset to make an area for driving along the borders of the parking lot. On the inside part, split into 12 double rows of parking, then split each double row into single rows that face each other, and then split each row into parking spaces. You could also make some the green space at the end of two of the rows by splitting out a section at the end of the two double rows. There are even car assets in /ESRI.lib/assets/Webstyles/Transportation (go to File -> Manage ESRI.lib to download these). Insert assets with i().
... View more
04-22-2020
05:02 AM
|
0
|
0
|
4898
|
|
POST
|
I can only answer some general cga questions. The i() operation inserts an asset. In this case, the asset is a .dae file, but the i() operation accepts other types as well. insert operation—CGA | Documentation @Hidden is an annotation written before an attribute that makes that attribute not appear in the Inspector. It does not affect the outcome of the code. It only controls whether or not an attribute will appear in the Inspector. Annotations—CGA | Documentation
... View more
04-20-2020
05:56 AM
|
2
|
2
|
2236
|
|
POST
|
True. It gets a bit messy when you have a lot of items in your mix. In 2019.1, it is possible to use an array to hold the mix percentages and then get an index into this array, which represents an item in your mix. const mix = [Mix_A, Mix_B, Mix_C, Mix_D, Mix_E, Mix_F, Mix_G, Mix_H, Mix_J]
const randNum = rand(0, getSum(mix))
const ind = getInd(randNum, 0, 0)
getSum(mix) = getSumRecursive(mix, 0, 0)
getSumRecursive(mix, currInd, currSum) =
case currInd==size(mix):
currSum
else:
getSumRecursive(mix, currInd+1, currSum+mix[currInd])
getInd(num, currInd, currSum) =
case currInd==size(mix):
-1
case num < currSum+mix[currInd]:
currInd
else:
getInd(num, currInd+1, currSum+mix[currInd])
Rule -->
case ind==0: A.
case ind==1: B.
case ind==2: C.
// ...
else: J.
... View more
04-20-2020
05:43 AM
|
1
|
0
|
1694
|
|
POST
|
It looks like the assets are not found. Do the assets for the goal and the ball exist in the correct folders (ex: assets/soccerField/esriBall.obj)? Are the corresponding mtl and texture image files also in the folder?
... View more
04-20-2020
02:56 AM
|
1
|
2
|
1466
|
|
POST
|
To do this in CGA, assuming you're starting with the building footprint, you can use the split operation to cut your building footprint in one direction and then cut the piece again in a second direction to get your parking lot. Then, to generate a parking lot, you could use split again to first cut out rows for parking and then divide each row into parking spaces. See also (another post): https://community.esri.com/message/908182-re-parking-lot?commentID=908182#comment-908291
... View more
04-20-2020
02:24 AM
|
1
|
2
|
4898
|
|
POST
|
This code makes a fence where the front is a different height than the other sides. It performs an offset on a lot and extrudes the offset borders such that the side facing the street front is a different height than the others. Lot -->
offset(-fence_depth)
comp(f) { inside=Lawn | border: r(90,0,0) Fence }
Fence -->
case geometry.isOriented(street.front):
r(-90,0,0)
extrude(fence_height_front)
else:
r(-90,0,0)
extrude(fence_height_other)
... View more
04-07-2020
02:39 AM
|
1
|
1
|
1938
|
|
POST
|
I'm not exactly sure what result you expected. What is wrong with the front and back extrusions in the screenshot? Did you want to create a fence around a lot where the fence on the street.front side is setback some distance while the fences on all other sides remain on the edge of the lot? If so, then I would recommend a different approach. In your code, performing an offset to get the border faces and then performing a setback on those faces is probably not what you intended because the setback is trying to perform setbacks on all 16 edges (4 edges per border face x 4 faces). I would recommend doing the setback first to get the polygon whose edges are where you want your fence to be. Then, create your fence. You can either create your fence by using offset and extrude (as you did in your code), or if you want a more complicated fence, you can use one of the fence rules from ESRI.lib. Lot -->
setback(comp(fe) {street.front: 5}) { all= Lawn | remainder= FencePolygon }
FencePolygon -->
offset(-fence_width)
comp(f) { inside= Lawn | border= extrude(fence_height) Fence. } Fence rules in ESRI.lib: Fence_On_Polygon.cga and Fence_On_Polygon_Simple.cga create fences along polygon edges. To use these, change the code as follows: import Fence_On_Polygon:"/ESRI.lib/rules/Fences/Fence_On_Polygon.cga"
FencePolygon -->
Fence_On_Polygon.Generate
... View more
04-01-2020
02:23 AM
|
0
|
3
|
1938
|
|
POST
|
Sorry, this is a bug. One thing you could do is use setNormals() or softenNormals() to recalculate the vertex normals, but this is not exactly what you want because it won't let you keep the original normals in the inserted object. It might, however, provide a better approximation to the vertex normals so that the lighting doesn't look so strange, or it might not look any better. The other caveat is that depending on the geometry connectivity, it may or may not need a cleanupGeometry(). setNormals operation—CGA | Documentation softenNormals operation—CGA | Documentation One hacky workaround to keep the original vertex normals would be to resize the object in the negative direction and then translate it. If the number of axes you invert is odd, then you need to also add a reverseNormals (if even, you don't need the reverseNormals). Here is the case to mirror something in x only. s('-1,'1,'1)
t('-1,0,0)
reverseNormals
... View more
03-18-2020
03:41 AM
|
0
|
0
|
1078
|
|
POST
|
I'm not sure. When you open the cga file, does the cga editor have any errors (red marks on the side)? Have you modified the cga file Building_From_Footprint.cga? I assume you have not. Are there any errors in the Log? (Window -> Log) Have you modified the cga file Tutorial_01_Essential_Skills__2019_1/rules/building_02.cga? Are there errors in the Problems view (Window -> Problems) if you reopen the scene Tutorial_01_Essential_Skills__2019_1/scenes/Essential_Skills_Part_5.cej? Were you trying to do the steps in Tutorial 1? Did this occur on a specific step in the tutorial? If so, which step? I noticed that there are inherently errors in Tutorial 1. To get rid of the errors, could you please add the following line of code to building_02.cga (anywhere in the file)? Does this eliminate the errors when you reopen the scene file? LotInner --> Lot Can you delete or rename (right click on project in Navigator -> Delete or Rename -> check box to delete on disk) and re-download Tutorial 01 (Help -> Download Tutorials and Examples)? When you open the scene again, do you still get the errors? Note: Deleting will cause you to lose any changes you made to Tutorial 1.
... View more
02-26-2020
07:28 AM
|
1
|
1
|
1910
|
|
POST
|
Vertical trim planes are automatically added after a comp for exactly this use case. It looks like the trim planes are already cutting your geometry in your screenshot since the ledges seem to be cut on an angle. Try doing center before primitiveCube. This is because when primitiveCube is inserted, the trim planes automatically cut the geometry, so when the cube is inserted first, the geometry is first cut (when it is in the wrong position), and then the cut geometry is centered. To see what I mean, remove the center, and see what you get. The help doc has a trim plane example where the scope is centered, and then the cube is inserted: comp operation—CGA | Documentation Here is some code which relies on the trim planes from the comp to create a ledge that meets in the corners. const ledge_height = 0.3
const ledge_depth = 0.1
Lot -->
extrude(10) Mass.
comp(f) { side: Facade }
Facade -->
split(y) { ~1: Floor.
| ledge_height: Ledge
| ~1: Floor. }
Ledge -->
s(scope.sx + 2*ledge_depth, '1, ledge_depth)
center(x)
primitiveCube
... View more
02-26-2020
03:06 AM
|
0
|
0
|
729
|
|
POST
|
Generating curved shapes in cga is really difficult. Instead, I would recommend inserting a pre-made asset in your case. Then, insert your asset(s) using i(). It is possible, however, to create simpler shapes like the tops of the Taj Mahal (see example linked below) by combining parts of a sphere and a cone. CGA offers the following 3D primitives: cube, sphere, cylinder, and cone. The resolution of sphere, cylinder, and cone primitives can be specified using the sides and divisions parameters. This means, you can make a cylinder whose top and bottom faces are hexagons (or any n-sided regular polygon). By splitting and combining primitives together (and maybe also combining some results from roof operations), it is possible to get some simple shapes, but this is basically the limit of cga. https://www.arcgis.com/home/item.html?id=d037b29aa9774797bb20bb047256adc2 To make something more complicated, you might be able to write a rule that builds the roof piece by piece from the bottom up using successive roofPyramid operations, or some other roof operation, with different angle settings on each level followed by split. But, this is complicated, and you don't want to be generating this kind of geometry for a roof piece, and it probably still won't even be possible to get the shape you want, so I don't recommend this. It is better to insert an asset.
... View more
02-26-2020
02:06 AM
|
0
|
0
|
870
|
|
POST
|
You are correct. The random number is evaluated, and the repeat split is applied using that number for all repeated parts. split(x) { rand(0,1): X. }*
// Let's say rand(0,1) gives us 0.3, then the split above is equivalent to the following:
split(x) { 0.3: X. }* In order to split into parts that have random sizes for each part, you can't use a repeat split. Instead, you should use a recursive split which recursively splits out one part at a time with a random size. Here is an example which recursively splits a shape into parts X that have random sizes between [0,1]. RecursiveSplit -->
case scope.sz<1:
X
else:
split(x) { rand(0,1): X
| ~1: RecursiveSplit }
Actually, since the split will just stop safely when there isn't any geometry left to split, then there is no need to even have the case statement as the end condition. The following is sufficient. RecursiveSplit -->
split(x) { rand(0,1): X.
| ~1: RecursiveSplit }
In your case, to alternate red, green, and blue colors, one way to do this would be: RecursiveSplit3 -->
split(x) { rand(0,1): color(1,0,0) X.
| rand(0,1): color(0,1,0) X.
| rand(0,1): color(0,0,1) X.
| ~1: RecursiveSplit3 }
... View more
02-17-2020
03:10 AM
|
1
|
0
|
2066
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 12-14-2022 07:18 AM | |
| 1 | 06-22-2020 04:54 AM | |
| 1 | 02-17-2020 03:10 AM | |
| 1 | 07-03-2023 03:37 AM | |
| 1 | 06-07-2023 05:26 AM |
| Online Status |
Offline
|
| Date Last Visited |
10-19-2023
12:40 PM
|