Juliensv Posted January 18, 2022 Share Posted January 18, 2022 Hello, I need to sequentially number a large number of LED Nodes so that they can be addressed and pixel mapped. These nodes are symbols which have a record attached, and I need to number them in the record field. I have already created polylines representing the signal path along the nodes, so my first thought was to write a script that essentially checks along the polyline and numbers each symbol in the order it finds them. I have written a script using DistAlongPoly to find x/y coordinates along the polyline in increments, and check these coordinates for a symbol using ForEachObjectAtPoint. However, it never seems to see the symbols. I have tried using just circles and it has worked just fine, but the symbols never seem to be picked up by ForEachObjectAtPoint! Do y'all know of other functions to select/modify symbols based on graphical coordinates? Or maybe there is another direction I can be going here? Attached is an example picture of the nodes and polyline, as well as the script I wrote. PROCEDURE NumberNodesAlongLine; VAR h, nodeHdl, DTHdl: HANDLE; x, y, z : REAL; dist, incr : REAL; tangent, pt : VECTOR; nodeList : ARRAY [1..341] OF HANDLE; nodeNum, i : INTEGER; symbolDef, recordDef, recordField : STRING; nodeMatch : BOOLEAN; FUNCTION CheckObjCallback(h : HANDLE) :BOOLEAN; {or FUNCTION CheckObjCallback(h : HANDLE; px, py : REAL) : BOOLEAN;} {or FUNCTION CheckObjCallback(h : HANDLE; px, py, pz : REAL) : BOOLEAN;} BEGIN {only polylines are okay} IF GetTypeN(h) = 21 THEN CheckObjCallback := TRUE; END; {tests the symbols given to it and adds them to an array if} {they are the right symbol, and are not already in the list} FUNCTION GetUniqueSymbolsList(objHdl : HANDLE) :BOOLEAN; BEGIN IF GetType(objHdl) = 6 THEN BEGIN{check if is symbol and correct definition} IF nodeNum = 0 THEN BEGIN {if first node, just add it to array} nodeList[1] := objHDL; nodeNum := 1; END ELSE BEGIN{check if node is already in array} nodeMatch := FALSE; FOR i:=nodeNum DOWNTO 1 DO BEGIN IF nodeList[i] = objHdl THEN BEGIN nodeMatch := TRUE; i:= 1; END; END; IF nodeMatch = FALSE THEN BEGIN{If Node is not already in array, add handle to array} nodeNum := nodeNum + 1; nodeList[nodeNum] := objHdl; END; END; END; GetUniqueSymbolsList := TRUE; END; BEGIN symbolDef := 'LED NODE'; recordDef := 'lED Node Data'; recordField := 'Node ID'; WHILE h = NIL DO {while no handle has been passed over, repeat the pick object function} BEGIN TrackObject( CheckObjCallback, h, x, y, z ); IF h <> NIL THEN SetSelect( h ); END; dist := 0;{starting distance} incr := 0.375;{increment of checking distance} nodeNum := 0;{Number of unique nodes found} {Checks along a polyline by increments and creates a list of unique nodes along the line} WHILE PointAlongPoly(h, dist, pt, tangent) DO BEGIN {Locus(pt[1],pt[2]);} ForEachObjectAtPoint(GetUniqueSymbolsList, 0, 0, pt[1], pt[2], 2); dist := dist + incr; END; FOR i:= 1 TO nodeNum DO BEGIN nodeHdl:= nodeList[i]; SetRField(nodeHdl, recordDef, recordField, Concat(i)); END; END; RUN( NumberNodesAlongLine ); Quote Link to comment
Maarten DE Posted January 18, 2022 Share Posted January 18, 2022 7 hours ago, Juliensv said: IF GetType(objHdl) = 6 THEN BEGIN{check if is symbol and correct definition} A symbol is type 15, 6 is an arc. Not sure if this is the only mistake, I haven't run the script. You could always try to debug your code, this could help you to see where it fails. Quote Link to comment
Pat Stanford Posted January 18, 2022 Share Posted January 18, 2022 I did try and run the script and couldn't make it work. Here is a really bad hybrid of your code and the way I would do it that does return the correct number of counts. In the attached file the squares are symbols. As long as the bounding box of the symbol is over the point along the poly (check points indicated by the loci) then the count increases. If the symbol is completely between the loci it is not counted. If you made the symbol bigger and it covered two check points, it will get counted for both. The script below is Script-2 in the attached file. PROCEDURE PTS_NumberNodesAlongLine; (*{$DEBUG}*) VAR H1, H2 : HANDLE; x, y, z : REAL; dist, incr : REAL; tangent, pt : VECTOR; nodeNum : INTEGER; L1 : LongInt; N1,N2 : Integer; Procedure PTS_CheckAtPoint; BEGIN L1:=FindObjAtPt_Create(Nil, 0,0, pt[1], pt[2], .001); N1:=FindObjAtPt_GetCount(L1); If N1>0 THEN BEGIN For N2:=1 to N1 DO BEGIN H2:=FindObjAtPt_GetObj(L1, N2); {AlrtDialog(Concat(Date(2,2),' ',GetType(H2)));} IF GetType(H2) = 15 THEN BEGIN {AlrtDialog(Concat(Date(2,2),' ',GetType(H2)));} nodeNum := nodeNum + 1; END; N2:=N2+1; End; End; END; BEGIN dist := 0;{starting distance} incr := 15;{increment of checking distance} nodeNum := 0;{Number of unique nodes found} H1:=FSActLayer; {Checks along a polyline by increments and creates a list of unique nodes along the line} WHILE PointAlongPoly(H1, dist, pt, tangent) DO BEGIN {Locus(pt[1],pt[2]);} PTS_CheckAtPoint; dist := dist + incr; END; AlrtDialog(Concat('NumNodes: ',nodeNum)); END; RUN( PTS_NumberNodesAlongLine ); GetObjects Along Poly.vwx 1 Quote Link to comment
Juliensv Posted January 19, 2022 Author Share Posted January 19, 2022 16 hours ago, Maarten DE said: A symbol is type 15, 6 is an arc. Not sure if this is the only mistake, I haven't run the script. Sorry! This is a holdover from when I was trying it with just circles rather than symbols. I have actually gotten this to work for my use case using PickObject, however the symbols need to be in the active class, the polyline in a different class, and the script sets the class options to Active Only, or else it only ever picks up the polyline, rather than the symbols. There is probably a way to make this symbol/record agnostic, but that's beyond my scope! 15 hours ago, Pat Stanford said: The script below is Script-2 in the attached file. Thank you so much for this! I have been struggling to wrap my head around the FindObjAtPt functions, and this is an extremely helpful example! I may try to reimplement my script using FindObjAtPt rather than PickObject if I ever need it in the future! 1 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.