Jump to content
Developer Wiki and Function Reference Links ×

Modifying/Finding Symbols based on graphical position/along a line?


Juliensv

Recommended Posts

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.

 

932214520_ScreenShot2022-01-18at9_08_30AM.png.8671130599ccf64d537ee8bddb3b7387.png

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 );

 

Link to comment

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

  • Like 1
Link to comment
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!

  • Like 1
Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...