Jump to content

MullinRJ

Member
  • Posts

    2,007
  • Joined

  • Last visited

Reputation

521 Spectacular

Personal Information

  • Occupation
    Circuit Board Designer
  • Location
    United States

Recent Profile Visitors

6,058 profile views
  1. Also try objects on the Screen Plane vs objects on the Layer Plane. Raymond
  2. @FMA, Assuming it does exist on your machine, why not try to use it to see what it does? 1) Draw an object. Start simple (line, rect, poly, text, etc.) and work your way up to more complicated objects (symbol, extrude, PIO, etc.) 2) Create a script. PROCEDURE xxx; VAR dx, dy, dz :Real; BEGIN CE_TransformVector(FSActLayer, 1, 1, 1); SysBeep; END; Run(xxx); 3) If it compiles, select one of your objects and run the script. 4) If it doesn't compile, try: PROCEDURE xxx; VAR dx, dy, dz :Real; V :Vector; BEGIN V := CE_TransformVector(FSActLayer, 1, 1, 1); Message(V); SysBeep; END; Run(xxx); 5) If you do get it to compile, try changing the constants for dx, dy, and dz and rerun the script to see what happens. Try (1,0,0), (1,1,0), (1,0,1), (2,1,1); (1,2,1); (1,1,2); etc. 6) Write back if you find anything interesting. Raymond
  3. The command must be distributor specific. I just placed your command as you defined it in a simple script and got the following syntax error: Line #10: CE_TransformVector(H, dx, dy, dz); | { Error: Identifier not declared. } The same error appears in VW 2023 and 2024. Raymond
  4. Hi Dave, Essentially vectors are a Structure of 3 numbers, or an Array of 3 numbers, under one variable name. There's lots of material online, but if you give me a call I can get you started quite quickly, especially in ways to use them in VW. PM me and we can setup a Skype, Zoom, or "other" conference call at your convenience. Seriously, call me, Raymond
  5. Good news, @Letti R, The bug is marked as Major and will be fixed relatively quickly. I have no idea what that means in real world time, but it definitely won't sit on the back burner. Like you, I await the fix. Raymond
  6. That's all well and good, but wait until you start writing longer scripts. Someday you'll want to look one up rather that recreate it. Either way, have fun. That's what It's all about. Raymond
  7. Hi @Pat Stanford, @DCarpenter, Here's an example using vectors, as requested, and a little more, 😉, though HScale2D() may be quicker for lines. Where this method may be more useful is when you are working with a Polygon and want to move a vertex without changing anything else. As with anything, "Actual mileage may vary." Scale a line using a vector approach: PROCEDURE xxx; { Test script to set new line length using vectors. } { 22 April 2024 - Raymond Mullin } VAR H :Handle; NewLength :Real; procedure SetLineLength(H :Handle; NewLength :Real); { Sets length of line H to new value NewLength. Point P1 is the anchor point.} Var P1, P2 :Vector; Begin GetSegPt1(H, P1.x, P1.y); GetSegPt2(H, P2.x, P2.y); P2 := P1 + UnitVec(P2-P1) * NewLength; SetSegPt2(H, P2.x, P2.y); End; { SetLineLength } BEGIN H := FSActLayer; NewLength := RealDialog('How long?', concat(hLength(H))); if not DidCancel then SetLineLength(H, NewLength); { changes line length to new value } SysBeep; { make noise when done } END; Run(xxx); If you want to scale the line in the other direction, swap the vectors P1 & P2 as shown in the following line. P1 := P2 + UnitVec(P1-P2) * NewLength; Here's an explanation of the expression: P2 := P1 + UnitVec(P2-P1) * NewLength; 1) Where P1 and P2 are both vectors, (P2-P1) is the vector that points from point P1 to point P2. Likewise, (P1-P2) is the opposite vector that points from point P2 to point P1. 2) UnitVec() is a function that scales a vector to have a length of "1". 3) A constant times a vector scales the vector, so scaling a unit vector by the new length results in a vector of the desired length. Essentially, the length is changed, but the direction remains the same. 4) Since vectors are positionless, adding a vector to a known point will return the point that is the correct distance and the correct direction away from the known point. PS - If you are wondering why I used Vector instead of Point as the variable's data type, The UnitVec() function does not accept Point type data. Essentially I am only working with 2D data, and Point and Vector are similar, but Vector data types work in all of the Vectorworks expressions, so I always use the Vector data type. In this case the z-component of the vector is always "0" and therefor does not contribute to any of the calculations. Using Vectors for 2D calculations saves having to do data conversions in the middle of a script between Points and Vectors. Feel free to try other ways as mine is not the only one. Raymond
  8. 😁 Good morning, @FMA. No, if that were the case it would have died from self inflicted abuse on my part years ago. As to your more frequent crashing, it can be caused by developing scripts. Restarting VW should clear most of your issues, as long as your code is eventually running smoothly, bu it would never hurt to restart your computer once and a while in the middle of doing a lot of development work. My experience is that excessive crashing goes away once I get my scripts running smoothly. YES – BACKUP OFTEN, especially when you are scripting. I will say one thing, if you lose a script because you crashed and it's not backed up, it's amazing how fast you can recreate it from memory versus create it from scratch. Been there, done that. Raymond
  9. Hi @Pat Stanford, Backups are current. Restore has yet to be voted upon. 🤔 Raymond
  10. @FMA, Like Pat, I, too, have often wondered if a BBox check would speed up processing for doing massive AddSurface operations, and like Pat, I never pursued it. After I posted last night I started to look at doing just that, but sleep happened before success and sleep won out. Today, I can confirm that testing bounding boxes for potential overlap is MUCH faster than using IntersectSurface() for the same evaluation. I ran a collection of 968 objects in a few seconds as compared to "hours?" as I presumed previously. And, I would post an example now, but my data hard drive died this afternoon. So until I get a new hard drive and restore the contents of my old one I'm going dark for a while. If you get a solution before then, post back. If not, maybe I can help you later. Raymond
  11. Hello @FMA, It looks like you pretty much nailed it. Two things – the first is just kibitzing. You can express your IF statements more concisely by using: IF ( temphandle <> NIL ) THEN BEGIN instead of: IF NOT ( temphandle = NIL ) THEN BEGIN OR NOT. Your code is syntactically correct and if it reads better to you, then leave it as is. The second – you should add a NIL test for your object in the inner loop. Change: IF NOT ( shadeOBJ[iOBJ] = shadeOBJ[iOBJn] ) THEN BEGIN to: IF NOT ( shadeOBJ[iOBJn] = NIL ) & NOT ( shadeOBJ[iOBJ] = shadeOBJ[iOBJn] ) THEN BEGIN The "&" symbol means "AND", so both clauses have to be TRUE to proceed. This way, you are only processing valid objects from your array. The shorter way to write it is: IF ( shadeOBJ[iOBJn] <> NIL ) & ( shadeOBJ[iOBJ] <> shadeOBJ[iOBJn] ) THEN BEGIN I don't know how many objects you typically want to process, but I timed a sample drawing with 1000 objects. It seemed to hang, so I restarted and selected 155 objects. The script took about 20 seconds. With 320 objects selected it took about 120 seconds. With that in mind you probably want to limit the number of objects to process to <300, and run your script multiple times on smaller selections. Actual times may vary. Nicely done, Raymond
  12. For my own benefit, I converted the first example above to Python. This may not be the most elegant function, but it works. If anyone wants to improve on it, please post an example. Thanks. def FSymFolder(): # Return a handle to the First Symbol Folder, if one exists, otherwise return Nil. # 20 Apr 2024 - Raymond Mullin SymFolderType = 92 Nil = vs.Handle(0) SymHnd = vs.FSymDef() # Symbol or Folder if (SymHnd != Nil): while (vs.GetTypeN(SymHnd) != SymFolderType): SymHnd = vs.NextObj(SymHnd) return SymHnd Raymond
  13. Whether you do it, or the engineers in the Mothership do it, it could potentially take a very long time to execute. For objects that have multiple intersection points, returning the answer(s) could also be quite unwieldy. Can you describe more specifically what you are trying to achieve? Some problems are much easier to solve than others. Trying to solve all possible combinations of all possible intersections is usually reason for finding a workaround or another approach. All the best, Raymond
  14. Hi @Letti R, Of course your folders are nested. Why would life be easy? The way to get the first folder is to look at everything in the Symbol Library and skip the symbols. Here are two Pascal routines that will return a handle to the First SymFolder. Hopefully you can convert them to Python easily. If not, write back and I can help. function FSymFolder :Handle; { Get a handle to the First Symbol Folder in the Symbol Library. } { 19 Apr 2024 - Raymond Mullin } Const SymFolderType = 92; Var SymHnd :Handle; Begin SymHnd := FSymDef; { Symbol or Folder } if (SymHnd <> nil) then while (GetTypeN(SymHnd) <> SymFolderType) do SymHnd := NextObj(SymHnd); FSymFolder := SymHnd; End; { FSymFolder } The same routine using ForEachObjectInList(). function FSymFolder :Handle; { Return a handle to the First Symbol Folder in the Symbol Library if one exists, otherwise return NIL. } { 19 Apr 2024 - Raymond Mullin } Const SymFolderType = 92; Var FldrHnd :Handle; function isFolder(H :Handle) :Boolean; Begin if (GetTypeN(H) = SymFolderType) then FldrHnd := H; isFolder := FldrHnd <> nil; { return True to stop } End; { isFolder } Begin { FSymFolder } FldrHnd := nil; { Folder handle } ForEachObjectInList(isFolder, 0, 0, FSymDef); { All objects, Shallow } FSymFolder := FldrHnd; End; { FSymFolder } Finding the Next Symbol Folder is similar to finding the first, but you start looking using a handle to the next object after the first Symbol Folder. Raymond
  15. Hello @Letti R, Yes, it is definitely a bug in VW 2024. I just filed a bug report for this, VB-203576, and cited this Forum post. If/when I hear anything I'll post back. For the moment you will need to shuffle resources between the old folders and the newly created nested folders. However, you don't need to shuffle things around initially as much as you describe above. Instead, create your new nested folder structure with dummy names, then move everything from your old folders straight into the new folders with SetParent(), which does work with moving resources between folders. When everything is moved, delete the two old folders and rename the dummy folders with the old folders' names. There is a caveat, there is always a caveat, if either of old folders contain nested folders you will have to create the finished folder hierarchy before you start shuffling anything, then very carefully move everything from its starting position to its final position, which can get tricky. I hope your two starting folders are flat (only contain resources.) Best wishes, Raymond
×
×
  • Create New...