I get my survey data as 2D DXF files, and I sculpt the topography of a site using Fredo’s Toposhaper ( TopoShaper | SketchUcation ). It takes an input of construction points as nodes for the topography. I find it VERY useful.
You need the construction points though in the first place, and I have automated the process of taking the DXF data and converting them into construction points at the correct Z-level.
Here is my process:
-
After importing the DXF file (which will be imported without text), import the text from the DXF file as Sketchup Text Labels. I use this plugin that I made to import text: SketchUp Plugins | PluginStore | SketchUcation . The model now looks like this:
-
Select the text labels that have the levels data in them (hopefully they are in their own layers/tags for each selection), and the points (crosses) that represent the point next to them. Group them to isolate them. The points (crosses) in my case are component instances, with its axis in the centre of the cross (this will be important later).
-
In the group, select all of the text labels with the level data and the points (crosses, which are component instances). Then run this script in the Ruby Console:
### SCRIPT for converting levels in text label to construction points.
### by TommyK 2022
### Use, copy, adapt, sell, however you like.
def is_number? string
true if Float(string) rescue false
end
# Make separate lists of Text and ComponentInstance entities
instances = []
texts = []
Sketchup.active_model.selection.each{ |ent|
if (ent.class == Sketchup::Text)
texts << ent
elsif (ent.class == Sketchup::ComponentInstance)
instances << ent
end
}
Sketchup.active_model.start_operation("Levels from Text")
# Run through all of the text labels to try to extract level data, and
texts.each{ |txt|
puts "adding point " + txt.text
# Find the instance representing the point on the survey which is closest to the text
instances_sorted = instances.sort_by{|inst| inst.transformation.origin.distance(txt.point)} # Sorts instances in order of distance to the text label. Uses the origin of the instance only
inst_point = instances_sorted[0].transformation.origin # Select the closest point to the text label.
if is_number?(txt.text)
height = Float(txt.text).m # <= assumes input of level is in metres. See https://ruby.sketchup.com/Numeric.html for other units: .cm .feet .inch. .km .m .mile .mm .yard can be used in its place.
point = Geom::Point3d.new(inst_point.x, inst_point.y, height)
#Sketchup.active_model.active_entities.add_cline(inst_point, point) # <= optional, if you like to see the lines from the instance to the new construction point
Sketchup.active_model.active_entities.add_cpoint(point) # adds the construction point at the correct level
end
}
Sketchup.active_model.commit_operation
If you’re lucky, you should have something like this:
… and it is ready for Fredo’s Toposhaper.
You can adapt the script to your specific situation.
You might find that you only need to take the x and y coordinates directly from the Text labels’ coordinates, so you might prefer to use this script instead (takes it straight from text label):
### SCRIPT for converting levels in text label to construction points.
### by TommyK 2022
### Use, copy, adapt, sell, however you like.
def is_number? string
true if Float(string) rescue false
end
texts = []
Sketchup.active_model.selection.each{ |ent|
if (ent.class == Sketchup::Text)
texts << ent
end
}
Sketchup.active_model.start_operation("Levels from Text")
# Run through all of the text labels to try to extract level data, and
texts.each{ |txt|
puts "adding point " + txt.text
if is_number?(txt.text)
height = Float(txt.text).m # <= assumes input of level is in metres. See https://ruby.sketchup.com/Numeric.html for other units: .cm .feet .inch. .km .m .mile .mm .yard can be used in its place.
point = Geom::Point3d.new(txt.point.x, txt.point.y, height)
#Sketchup.active_model.active_entities.add_cline(inst_point, point) # <= optional, if you like to see the lines from the instance to the new construction point
Sketchup.active_model.active_entities.add_cpoint(point) # adds the construction point at the correct level
end
}
Sketchup.active_model.commit_operation
Let me know if you end up using this script