Friday, February 14, 2025

Almost sometimes biennial proof of life.

 Recent conversation about a particular legend in a particular field went something like "Did you realize he was that old?" and my first thought was "I didn't even realize he was still alive!".  Makes me wonder how many people think that when the look at such a long-ignored blog.  Well I'm not that old and I am still alive and the question I was asked was "Are you still writing any python?", to which the answer is yes almost daily but I also realize that no one really cares.

I did pass off my "BeginnersVrPython3.py" script to someone and realize that I should make a quick video to document what it does in case anyone in the office wanted to start plinking on coding some python.

It can be found at

https://rumble.com/v6ezy07-cardinal-systems-vrone-vrtwo-08-beginning-vrpython.html

and the script can be found at

https://drive.google.com/file/d/1Kyt0bkb0qPEAgtl7HriiFfjVmt7s0dzh/view?usp=sharing

Feel free to contact me at the email in the script if you have any questions.

Tuesday, November 07, 2023

Placing Lines Within Polygons Uniquely

 I'll be honest, there might be a function to do this but I couldn't find it and it was only going to take a few minutes so let's take a look.  I have a bunch of triangles for and  XML file that need to be subdivided into areas that are defined by polygons.  I need to make sure that the triangles are kept intact and that there are no duplicates.  In my case it didn't need to be an exact science and I wasn't worried about the edges.  My solution was to check each triangle against a polygon and if the first point of the triangle was within the polygon it would be flagged, or in this case the layer changed.  I just banged it out and I may make changes but for now it does the trick.

print ('line_change_line_in_polygon.py modified   06:25 2023/11/07')
# Change layer of line that starts within polygon.

'''
Author: Dennis Shimer dshimer@gmail.com
License: cc-by-sa  http://creativecommons.org/licenses/by-sa/3.0/
'''

Ws=PyVrWs()
Line=PyVrLine()
BoundingLine=PyVrLine()
Gui=PyVrGui()

CheckLayer=600
NewLayer=1001
PointsFound=0
WsNum=Ws.Aws()

PromBox = VrPromBox ('Check lines in Polygon.', 30, 1)
PromBox.AddInt ('Layer to check', CheckLayer, 1, 32000)
PromBox.AddInt ('Change layer to', NewLayer, 1, 32000)
if (PromBox.Display(0) == 0):
CheckLayer=PromBox.GetIntByPrompt('Layer to check')
NewLayer=PromBox.GetIntByPrompt('Change layer to')
BoundingLine.Id()
print (CheckLayer,BoundingLine.GetLayer())
Gui.ProgInit('Lines',Ws.GetLineCount(WsNum))
for EntNum in range ( Ws.GetLineCount(WsNum)):
Gui.ProgSet(EntNum)
if CheckLayer == Ws.GetLineLayer(WsNum,EntNum):
Line.Load (WsNum, EntNum)
X,Y,Z=Line.GetPoint(0)
if BoundingLine.IsPointInside (X,Y):
# print (X,Y,Z)
PointsFound=PointsFound+1
Line.SetLayer(NewLayer)
Line.ReRec(1)
# Line.Plot()
Gui.ProgReset()
print (PointsFound)


 

Tuesday, September 25, 2018

Modifying LiDAR Intensity in Vr Applications

I actually don't have the patience to look back through posts with regard to modifying LiDAR data so I'll just drop this one in as an example of how simple it can be.  This will have limited usefulness because it is fixing an apparent shortcoming in Vr that will no doubt be rectified at any moment, but hopefully the example will continue to be useful.  The current problem is that points created via dsmare (DSM Area) have a nice RGB value, but sometimes it would be nice to have Intensity as well. Rather than making it tricky I found that if I just add the R, G, and B values and divide by 3 it provides a useful "intensity like" display.    
There are only a couple lines that do anything productive so I'll just explain them.

print 'rgb2int.py modified 12:23 PM 9/25/2018'
# Set point intensity based on rgb
'''
License: cc-by-sa  http://creativecommons.org/licenses/by-sa/3.0/

'''
Ws=PyVrWs()
Punt=PyVrPunt()
Gui=PyVrGui()
WsNum=Ws.Aws()
PointBufferCount=Ws.GetPuntBufCount(WsNum)

Gui.ProgInit('Points',Ws.GetPuntBufCount(WsNum))
for PointBufferNumber in range(PointBufferCount):
    Punt.Load(WsNum,PointBufferNumber)
    Gui.ProgSet(PointBufferNumber)
    for PuntNum in range(Punt.GetCount()):
        x,y,z,PuntA,r,g,b= Punt.GetPuntRgb (PuntNum)
        PuntA['Int']=int((r+g+b)/3)
        Punt.ChgPuntA (PuntNum, PuntA)
    Punt.ReRec()
Gui.ProgReset()
PyVrGr().Replot()
 You need to have a PyVrPunt object to work with.  This object will be used to load up a "Point Buffer" full of LiDAR data which we can then step through the individual point data.  Note that you need to loop over the whole file loading each of the point buffers into the Punt object. This is done with the first for loop

for PointBufferNumber in range(PointBufferCount):

As we step through all the buffers, each one needs to be loaded and then it will be stepped through loading up the individual points hence the next for loop.

for PuntNum in range(Punt.GetCount()):

There are several ways to get particular data items from individual points and much of the data is stored in an attribute dictionary known as PuntA.  Many times I just load up PuntA, query it, make decisions, then make changes based on what I find.  In this case it is handy that the method that extracts the R,G,B data also pulls out PuntA at the same time because Intensity is stored within PuntA.  The first thing that needs doing is grabbing the data for the individual point.


x,y,z,PuntA,r,g,b= Punt.GetPuntRgb (PuntNum)

Then we just turn right around and push the intensity into the current PuntA dictionary and record the modified attributes back to the point.


PuntA['Int']=int((r+g+b)/3)
Punt.ChgPuntA (PuntNum, PuntA)


Once all the points are changed in the currently loaded buffer (Punt), the whole buffer can be re-recorded.


Punt.ReRec()

The Punt class is fully documented in the Python Programming section of the documentation but it basically comes down to knowing if you are creating or modifying something inside the attribute dictionary or outside it and working with the appropriate methods.

Wednesday, September 13, 2017

Musings on being a senior programmer

In some context's the title would mean being an experienced, admired, authoritative person.  Alas for me it just means being old, and in retrospect using the word programmer is a bit of a stretch.  Maybe it is harder to remember things because every day I have so much more important information to pack away for later retrieval, or maybe it is just harder to remember.  As we evolve as a company I find myself adding layer names and function keys that I know I'll use again but not often enough that I'll probably remember them.  Gone are the days when a function was one of 120 three digit numbers (which of course I still remember because I've been using most of them for 30 years). I quit trying to remember things I can Google long ago so why not treat the new layers and functions the same, after all if I expose myself to them often enough I'll eventually remember, and if I don't then searching is easy enough.  Enter sealay and seafk.  Now if I forget what the layer number is, but remember that it had the word "Wall" in the name I can just
sealay wall
and like magic I am presented with a list of options which when selected issues a lay= command.

  Likewise if I forget a function key and don't want the entire funkey command list I can just...
seafk odot
and all the appropriate function keys are presented.

It must be nice to have a limitless unhindered storage capacity, but for those of us who have more useful years in the past than in the future, search is our friend.

They both essentially work the same, just one searches the layer names and one searches the function keys.  Here is an example but you get the idea.

print 'seafky.py modified 9:11 AM 7/27/2017'# Display FKeys matching search string
'''
Copyright 2017 Dennis Shimer
Vr Mapping copyright Cardinal Systems, LLC
No warranties as to safety or usability expressed or implied.
Free to use, copy, modify, distribute with author credit.

Prompts user for Fkey name (or any part) then displays Fkey
'''

def lines2lists(AListOfDataLines):
    DataList=[]
    for Line in AListOfDataLines:
        DataList.append(Line.split())
    return DataList

PrintList=[]

if VrArgs:
    SearchText=VrArgs[0]
else:
    SearchText=PyVrGui().InputDialog ('Search String', 'Partial Funkey Name')[1]

FunKeyFile = open(VrCfg().GetFkeyFileName() , 'r')
FunkeyData = FunKeyFile.readlines()
FunKeyFile.close()
DataList = lines2lists(FunkeyData)

for DataLine in DataList :
    if len(DataLine) == 3 :
        if DataLine[1]=='KeyName':
            if DataLine[2].upper().count(SearchText.upper()):
                PrintList.append(DataLine[2])

if PrintList:
    PromBox = VrPromBox ("Run Fkey", 60, 1)
    PromBox.AddList ("Function Key", 40, len(PrintList)+1, 0)
    for FkeyItem in PrintList:
        PromBox.AddListItem (FkeyItem)
    if (PromBox.Display(0) == 0):
        RunFkey = PromBox.GetListByPrompt ("Function Key")
    else: RunFkey=0
    if RunFkey : PyVrGui().PushKeyin(RunFkey)
    else: PyVrGui().MsgBox('No Match to {:s}'.format(SearchText), 'Matching Layers')

Tuesday, September 20, 2016

Going from Zero to "How did I ever get along before that" in three minutes

The other day I heard about a little indicator app ( aka bookmarks-indicator ) for Ubuntu that sits nicely on the task bar and allows you to drill down through the disk hierarchy by simply mousing over the icon.  It displays the folder names as you move through the system, auto expanding as you pause over a file name, showing individual files in each folder and opening them when you click.  One minute I didn't even know I wanted this ability and three minutes later I wondered how I ever survived without it.  The fact that is was just a couple dozen easy to read lines of python was even funner.  

Jump ahead to this morning and I came across a bunch of lines that just needed to have one particular point removed from them.  Long story, but on this particular job it happens on a fairly regular basis.  Well I've always had a program to straighten a line, removing all points between to identified locations, but I just needed to delete one point, and doing it with a single click would just be that much easier.  Granted EditVertex set to delete is 95% of the way to what I want but honestly sometimes you just need to step outside for a break to grab that last 5% especially if you can do so with a few lines of code.  And let's be honest it's funner than working anyway.

Hence dellpt.py

print 'dellpt.py modified 9:06 AM 9/20/2016'
# Delete Line Point
'''
Copyright 2016 Dennis Shimer
Vr Mapping copyright Cardinal Systems, LLC
No warranties as to safety or usability expressed or implied.
Free to use, copy, modify, distribute with author credit.

Deletes a single point identified on a line.
'''

Ws=PyVrWs()
Line=PyVrLine()
while Line.Id() != -1:
    Ws.UndoBegin(WsNum,"dellpt")
    PntNum=Line.GetIdPoint ()
    Line.DelPoint (PntNum)
    Line.ReRec()
    Line.Plot()
    PyVrGr().Replot()
    Ws.UndoEnd(WsNum)

For anyone interested in trying VrPython for the first time or if you are early in the game, I suggest going to the earliest posts and working forward. I use VrPython every day for many wonderful things, needless to say it will change and could potentially damage a file. Any risk associated with using VrPython or any code or scripts mentioned here lies solely with the end user.

The "Personal VrPython page" in the link section will contain many code examples and an organized table of contents to this blog in a fairly un-attractive (for now) form.