Jump to content


  • Posts

  • Joined

  • Last visited


516 Spectacular

Personal Information

  • Occupation
    Circuit Board Designer
  • Location
    United States

Recent Profile Visitors

6,013 profile views
  1. 😁 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
  2. Hi @Pat Stanford, Backups are current. Restore has yet to be voted upon. 🤔 Raymond
  3. @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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. Hello @DCarpenter, Immediately after EndXtrd, get the handle to your new object with LNewObj. Create two new variables: "Hxtrd" to store the handle to the Extrude; and "Hdup" to store the handle to the extrude duplicate. PROCEDURE xxx; VAR Hxtrd, Hdup :Handle; BEGIN BeginXtrd(5", 10"); Rect(0, 0, 24, 12); EndXtrd; Hxtrd := LNewObj; { handle to the extrude } Hdup := hDuplicate(Hxtrd, 0, 0); { handle to a duplicate extrude } Move3DObj(Hxtrd, 40, 20, 30); { move it anywhere you want } SysBeep; { make noise when done } END; Run(xxx); Raymond
  10. Hello @FMA, I don't believe you can write to your open READ file. You will need to close it first, and reopen it with Rewrite(), or Append(). Then you can write to it. Rewrite() will write over any existing data, and Append() will add to the end of existing data. Don't forget to close it again when you are finished writing. HTH, Raymond
  11. Hello @Arnold_Hoekstra, I tried opening your file in several versions of VW and MiniCAD (VW12, VW8, MC7, MC6, MC5, & MC4) to no avail. It appears the file is damaged. Do you have another copy? When I downloaded the file, it had no File Type or Creator codes assigned. I added MC+4 / CDP3 for MiniCAD 4 &5 files, which did not work. Then I tried MC6d / CDP3 for MiniCAD 6 files. This also did not work. I got one of two messages, "This file is damaged!", or "Resource Manager error!". If this is your only copy, you might want to send it to the VW engineers to see if they can resurrect it. Good luck, Raymond
  12. Hi @Dave Donley, I just took a peek at the file you uploaded today. It opens in VW 2024, but there is nothing showing. The Resource Manager has 10 LineStyles, and two Textures (Water Bright, and Water Dark.) Also, there is one Design Layer, visible, and two Classes (None and Dimension), both visible. Would you please verify on you end? Thank you, Raymond
  13. Hi Sam, On a Design Layer, I don't think so. In a Viewport, maybe, but probably not by the PIO's control. Others may prove me wrong. Without knowing more of what you are trying to achieve, I don't know what else to add. Raymond
  14. Hello @ge25yak, There may be other ways to set the wall height, but I found this works, so I stopped looking for other ways. The commands below always use mm, so you have to convert your document units to mm before setting the wall height values, hence the use of the scale factor variable "SF". This overly simple script will change the selected wall height to 5 (document units). I assumed meters in this case. Using your document units change the "newWallHt" value to your liking. import vs # Sample script to set the height (top elevation) of a selected wall. newWallHt = 5 # document units WallStartHeightTop = 604 WallEndHeightTop = 606 WallStartHeightBot = 605 WallEndHeightBot = 607 SF = vs.GetPrefReal(152) / 25.4 # units per mm H = vs.FSActLayer() vs.SetObjectVariableReal(H, WallStartHeightTop, newWallHt/SF) # starting height in mm vs.SetObjectVariableReal(H, WallEndHeightTop, newWallHt/SF) # ending height in mm vs.ResetObject(H) vs.SysBeep() HTH, Raymond
  15. Hi @Andreas, Yes, that is the call to insert a symbol/pio into a wall. Using VW to help reverse engineer the code, I placed a Window in Wall and exported the VW file to a script file that defines the geometry. Use menu File>Export>Export Script... This doesn't always work for complicated files, but for simple things it's a great way to see what calls are used and how they are arranged. Here's a small script I built by copying the Wall and Window from the text dump (Export Script...). I found the relevant calls in the middle of the file and copied them to a new file, then rearranged a few calls and renamed the temp handles to make it easier to follow. Comments were also added for readability. To see what this represents, copy and paste this code into a script resource and run it. Then change some number, rerun, and notice the effects of the changes. It's a great learning tool for new commands. PROCEDURE xxx; { Sample script to insert a Window into a Wall. The units are in mm. } VAR WallHandle, WindowHandle :Handle; boolResult :Boolean; BEGIN { set pen and fill attributes } PenSize(1); PenPatN(2); FillPat(1); PenFore(0, 0, 0); PenBack(65535, 65535, 65535); FillFore(0, 0, 0); FillBack(65535, 65535, 65535); NameClass('None'); { set class to use } Wall(-5400, 2000, 5000, 2000); { create a wall } SetObjectVariableReal(LNewObj, 604, 3048); { Wall Start Height Top } SetObjectVariableReal(LNewObj, 605, 0); { Wall Start Height Bottom } SetObjectVariableReal(LNewObj, 606, 3048); { Wall End Height Top } SetObjectVariableReal(LNewObj, 607, 0); { Wall End Height Bottom } SetObjectVariableReal(LNewObj, 621, 3048); { Wall Overall Height Top } SetObjectVariableReal(LNewObj, 622, 0); { Wall Overall Height Bottom } SetObjectVariableReal(LNewObj, 618, 152.4); { Set Wall Width } DoubLines(152.4); ClearCavities; { start with an empty wall } WallHandle := LNewObj; { save handle to the Wall } WallCap(FALSE, TRUE, FALSE, 0, 0); AddSymToWallEdge(LNewObj, 5300, 0, FALSE, FALSE, 'Window', 0); { insert object into wall } boolResult := SetObjWallInsLocOff(LNewObj, WallHandle, 0); { shifts object to inside/outside of wall } WallCap(TRUE, TRUE, FALSE, 0, 0); ResetObject(WallHandle); { reset the Wall object } WindowHandle := LNewObj; { save handle to the Window - not used, but could be used later } SysBeep; { make noise when done } END; Run(xxx); Here's the same thing in Python. Again, the code was gathered from text dump from the program using Export Script. import vs # Sample Python script to insert a Window into a Wall. The units are in mm. # set pen and fill attributes vs.PenSize(1) vs.PenPatN(2) vs.FillPat(1) vs.PenFore((0, 0, 0)) vs.PenBack((65535, 65535, 65535)) vs.FillFore((0, 0, 0)) vs.FillBack((65535, 65535, 65535)) vs.NameClass('None') # set class to use vs.Wall(-5400, 2000, 5000, 2000) # create a wall vs.SetObjectVariableReal(vs.LNewObj(), 604, 3048) # WallStartHeightTop vs.SetObjectVariableReal(vs.LNewObj(), 605, 0) # WallStartHeightBottom vs.SetObjectVariableReal(vs.LNewObj(), 606, 3048) # WallEndHeightTop vs.SetObjectVariableReal(vs.LNewObj(), 607, 0) # WallEndHeightBottom vs.SetObjectVariableReal(vs.LNewObj(), 621, 3048) # WallOverallHeightTop vs.SetObjectVariableReal(vs.LNewObj(), 622, 0) # WallOverallHeightBottom vs.SetObjectVariableReal(vs.LNewObj(), 618, 152.4) # SetWallWidth vs.DoubLines(152.4) vs.ClearCavities() # start with an empty Wall WallHandle = vs.LNewObj() # save handle to the Wall vs.WallCap(False, True, False, 0, 0) vs.AddSymToWallEdge(vs.LNewObj(), 5300, 0, False, False, 'Window', 0) # insert object into wall boolResult = vs.SetObjWallInsLocOff(vs.LNewObj(), WallHandle, 0) # shifts object to inside/outside of wall vs.WallCap(True, True, False, 0, 0) vs.ResetObject(WallHandle) # reset the Wall object WindowHandle = vs.LNewObj() # save handle to the Window - not used, but could be used later vs.SysBeep() # make noise when done One caveat to keep in mind, LNewObj is a function that returns a handle to the last object created (usually — but Groups don't follow this rule when they get created.) Think of LNewObj as a temporary handle. If you want to save a handle for use later in the script, assign LNewObj to a program variable and keep on drawing. Notice "WallHandle" is used this way. HTH, Raymond
  • Create New...