The purpose is to have correct Existing Site Model in order to design Proposed one and include it (Proposed) also in sections of building. The start is existing Site Model. I've identified the possible workflow to create existing Site Model in 3D from 2D topographic file received from surveyors. The trick is this task is required to be done rarely (once per project) and I'm lacking that level of programming knowledge to code it in reasonable time (comparing amount of time I should invest and time I would save). I assume the script allowing to make 3D from 2D would be advantageous to many architects & landscape architects and therefore some kind of collaboration here on developing it could be possible. If not, I hope at least to receive some coding advise (experienced programmer may find it relatively easy).
There are 2 ways how Z data is represented in 2D surveyor files I deal with (mostly created with Microstation and then exported to DWG):
1. Text object displaying Z value. Insertion point of text object (or upper left point of text objects bounding box) gives X and Y.
2. Multiple text objects combined with liner object (mostly polygon, sometimes line, few times polyline), I think in AutoCAD Civil 3D it was named "feature line". This line determines where the border between various relief types are. For example, it divides road, flat area, slope, ditch, hill.
Working with text objects only as 3D point source data gives very rough and sometimes inadequate result. Therefore usage of "feature lines" is a must-have. Polygons forming "feature line" have at least 2 text objects on them, sometimes they are closed and sometimes not. They are very varying, besides sometimes text isn't exactly on the line but some distance (6mm) away, if printed it looks like on the polygon but digitally it isn't. Additionally, sometimes length of segment is unreasonably small (3 mm).
For example, closed polygon forming lawn in the backyard has perimeter of 80m, has 115 segments and 16 text objects on it. Another closed polygon at the foot of hill has perim 45m, 51 segments and 6 text objects. Linear (unclosed) polygon forming side of the road has perimeter 51m, 5 segments and 6 text objects.
The meaning of 3D points (for convenience I'll call text objects 3D points) on polygon is as follows:
1. draw a 3D line from 1 3D point to another;
2. duplicate in Top view and move perpendicularly;
3. create plane using those 2 3D lines;
4. projection of polygon's segments (located between 2 3D points) on this plane would give Z value of each segment.
5. Then you take next 2 3D points (point No2 and point No3) and repeat.
My workflow is to create Stake Objects as source data for Site Model. Couldn't make much use of 3D Polys (since couldn't find reasonable way to create them from data given). Probably 3D Polys would be the way...
My vision on how it should work:
1. User selects a poly which is to be transformed into 3D Poly and fires the command (this script).
2. The script checks for text objects which lie on this polygon (with tolerance of 20 mm) and which are to be used as 3D points to create 3D Poly. PtOnLine could be used.
3. Performs some really nice calculations (don't have clue on this part) which uses all given data and creates 3DPoly on another layer.
4. Deletes text objects which were used as 3D points.
* A step further would be to perform this command automatically on all polygons in specific class and in current layer.
Currently I'm doing these actions to have Stake Objects as valid data:
1. Select all polygons forming 1 linear object and all texts lying on that "feature line".
2. Run the script TOPO STEP 1:
PROCEDURE TopoApstradesSkripts;
VAR
Criteria, InitialLayerName: STRING;
PROCEDURE SelectObjectsInCurrentLayer(DeSelect: BOOLEAN; ObjectType: STRING);
VAR
Criteria: STRING;
BEGIN???
Criteria:=concat('(L=',chr(39),GetLName(ActLayer),chr(39),') & (T=',ObjectType,')');
IF DeSelect=true THEN DSelectAll;
SelectObj(Criteria);
END;
{---- ---- ---- ---- ---- ---- ---- ----}
BEGIN???
DoMenuTextByName('Cut',0);
Layer('paligmodelis');
DoMenuTextByName('Select All',0);
DoMenuTextByName('Clear',0);
DoMenuTextByName('Paste In Place',0);
SelectObjectsInCurrentLayer(true,'Poly');
SelectObjectsInCurrentLayer(false,'Polyline');
SelectObjectsInCurrentLayer(false,'Line');
DoMenuTextByName('Cut',0);
Layer('teritorijas konturas');
DoMenuTextByName('Paste In Place',0);
DoMenuTextByName('Compose',0);
IF NumSObj(ActLayer)>1 THEN AlertCritical('Par daudz objektu!','Izveido 1 veselu!') ELSE
BEGIN
IF GetLS(LSActLayer)<>2 THEN SetLS(LSActLayer,2);
DoMenuTextByName('Copy',0);
DSelectAll;
Layer('paligmodelis');
DoMenuTextByName('Paste In Place',0);
DSelectAll;
END;
END;
RUN(TopoApstradesSkripts);
3. Duplicate Text Objects to create temporary Site Model giving approx correct planes for "feature line" segments. This Site Model has to be wider that the poly in order via Duplicating Along Path... (this poly) Stake Objects they could display elevation.
4. Run the script TOPO STEP 2. Thanks to dspearman for Text 2 Stake conversion script (it's adapted here):
PROCEDURE TopoApstradesSkripts;
VAR
Criteria, InitialLayerName: STRING;
PROCEDURE SelectObjectsInCurrentLayer(DeSelect: BOOLEAN; ObjectType: STRING);
VAR
Criteria: STRING;
BEGIN???
Criteria:=concat('(L=',chr(39),GetLName(ActLayer),chr(39),') & (T=',ObjectType,')');
IF DeSelect=true THEN DSelectAll;
SelectObj(Criteria);
END;
PROCEDURE SelectPIOsInCurrentLayer(DeSelect: BOOLEAN; ObjectType: STRING);
VAR
Criteria: STRING;
BEGIN???
Criteria:=concat('(L=',chr(39),GetLName(ActLayer),chr(39),') & (PON=',chr(39),ObjectType,chr(39),')');
IF DeSelect=true THEN DSelectAll;
SelectObj(Criteria);
END;
FUNCTION Text2Stake(h :HANDLE) :BOOLEAN;VAR???r, g, b :LONGINT;
p1X, p1Y, p2X, p2Y ,p2Z:REAL; NewStake:HANDLE;
Objtext:STRING;
BEGIN
IF GetType(h)=10 THEN
BEGIN
Objtext:=GetText(h);
p2z:=Str2Num(Objtext);
GetBBox(h,p1X, p1Y, p2X, p2Y );
NewStake:=CreateCustomObjectN('Stake Object',p1x,p1y,0,False);
SetRField(NewStake,'Stake Object','Mode', 'Include as site model data');
SetRField(NewStake,'Stake Object','Style', 'Triangle');
SetRField(NewStake,'Stake Object','Scale Factor', '0.2');
Move3DObj(NewStake,0,0,p2z);
END;
END;
{---- ---- ---- ---- ---- ---- ---- ----}
BEGIN???
SelectObjectsInCurrentLayer(true, 'Text');
ForEachObjectInLayer(Text2Stake, 2, 0, 0);
SelectObjectsInCurrentLayer(true, 'Text');
DoMenuTextByName('Clear',0);
SelectPIOsInCurrentLayer(true, 'Stake Object');
END;
RUN(TopoApstradesSkripts);
5. Create Site Model, select polygon and 1 stake.
6. Run the script TOPO STEP 3:
PROCEDURE TopoApstradesSkripts;
FUNCTION SetStakeNoLabelElevationMode(h :HANDLE) :BOOLEAN;
BEGIN
SetRField(h,'Stake Object','Mode', 'Set elev to site model');
SetRField(h,'Stake Object','Label Reference', 'No Label');
ResetObject(h);
END;
{---- ---- ---- ---- ---- ---- ---- ----}
BEGIN
ForEachObjectInLayer(SetStakeNoLabelElevationMode, 2, 0, 0);
{ DoMenuTextByName('Duplicate Along Path',0);}
END;
RUN(TopoApstradesSkripts);
7. Duplicate along path (I was trying to get some help do this programmatically):
8. Run the script TOPO STEP 4:
PROCEDURE TopoApstradesSkripts;
FUNCTION SetStakeNoLabelSiteDataMode(h :HANDLE) :BOOLEAN;
BEGIN
SetRField(h,'Stake Object','Mode', 'Include as site model data');
SetRField(h,'Stake Object','Label Reference', 'No Label');
ResetObject(h);
END;
{---- ---- ---- ---- ---- ---- ---- ----}
BEGIN
ForEachObjectInLayer(SetStakeNoLabelSiteDataMode, 2, 0, 0);
DoMenuTextByName('Cut',0);
Layer('reljefa modelis');
DoMenuTextByName('Paste In Place',0);
Layer('paligmodelis');
DoMenuTextByName('Select All',0);
DoMenuTextByName('Clear',0);
Layer('starta topo');
END;
RUN(TopoApstradesSkripts);
9. Repeat until done. Then create my Site Model from stakes in DL "reljefa modelis".
For having clear picture I attach also VW file of my topo data. Take it as is (some names in Latvian). Any thoughts are welcome!