Jump to content

MullinRJ

Member
  • Posts

    1,993
  • Joined

  • Last visited

Everything posted by MullinRJ

  1. @KingChaos I've annotated the code you posted to show you what each line does. Then further down I offer you some options for rewriting it that may make it easier to follow. {Object Creation Code} { this sets the active class – optional } NameClass('Keine'); { the extrusion starts with this statement } BeginXtrd(0,500); { these lines define stroke, fill, and color attributes } PenSize(4); PenPatN(2); FillPat(1); PenFore(0,0,0); PenBack(65535,65535,65535); FillFore(0,0,0); FillBack(65535,65535,65535); { this is the shape to be extruded } RectangleN(0,0,1,0,890,680); { these lines define a drop shadow, which is not used so can be deleted } objectHandle := LNewObj; SetDropShadowData(objectHandle, 0,0.1,0.05,#315d,75,0,0,0); EnableDropShadow(objectHandle, FALSE); { the extrusion ends with this statement } EndXtrd; { *** you need an EndXtrd statement to make it work **** } To simplify the above code I've rewritten it here, adding comments, spaces, and removing dead code: { these lines define stroke, fill, and color attributes } { they may be included or excluded as desired } PenSize(4); PenPatN(2); FillPat(1); PenFore(0,0,0); PenBack(65535,65535,65535); FillFore(0,0,0); FillBack(65535,65535,65535); NameClass('Keine'); { set the active class – optional } { these next three lines draw the geometry } BeginXtrd(0,500); { the extrusion starts here } RectangleN(0,0,1,0,890,680); { this is the shape to be extruded } EndXtrd; { the extrusion ends here } Using @Jesse Cogswell's approach, here is another rewrite: BeginXtrd(0,500); { the extrusion starts here } RectangleN(0,0,1,0,890,680); { this is the shape to be extruded } EndXtrd; { the extrusion ends here } { the following lines are optional, and they only refer to the previously created extrude } SetClass(LNewObj, 'Keine'); { set the object's class } SetLW(LNewObj, 4); { 4 mils wide } SetLSN(LNewObj, 2); { use pen foreground color - solid } SetFPat(LNewObj, 1); { use fill background color - solid } SetFillFore(LNewObj, 0,0,0); { black } SetPenFore(LNewObj, 0,0,0); { black } SetFillBack(LNewObj, 65535,65535,65535);{ white } SetPenBack(LNewObj, 65535,65535,65535); { white } Note the use of LNewObj to reference the previously created object. Lastly, to make this adaptable to a PIO I added "p" variables where you would want to control your code. Open the Plug-In Editor to start defining your plug-in object. (Cmd-Shift-Z on a Mac, or Ctrl-Shift-Z on a PC.) Click on the NEW... button, give it a name, and select a PIO type. If you start with a Point Object PIO you will need to create three variables. Let's assume you choose the names, Length, Width, and Extrude. These are defined in the Plug-in Editor, under the Parameters tab. Make them type Dimension. In your script you will refer to these values as PLength, PWidth, and PExtrude, respectively. In your code, these are constants which means you can't change their values. Technically, you can, but it will have no effect on anything when you are done. The only lines you will need to edit are these: BeginXtrd(0, PExtrude); { the extrusion starts here } RectangleN(0, 0, 1, 0, PLength, PWidth); { this is the shape to be extruded } EndXtrd; { the extrusion ends here } Now you can paste the code into the PIO Editor, wrapped in the basic Pascal program shell. Add any of the Class, Color, or Pen & Fill commands you think are necessary and you have a simple plugin that has user defined ∆XYZ components. Note – if you assign Color and Class inside your plug-in, you won't be able to change them from the outside. Here's the minimum code that will draw an extruded box with parameters showing in the OIP: PROCEDURE xxx; BEGIN BeginXtrd(0, PExtrude); { the extrusion starts here } RectangleN(0, 0, 1, 0, PLength, PWidth); { this is the shape to be extruded } EndXtrd; { the extrusion ends here } END; Run(xxx); Now when your code runs you will be able to change all of its parameters in the OIP. The very last step is to add your plug-in to you workspace as a TOOL , and you can then place it in your drawing with a click. HTH, Raymond
  2. Sadly, there is no Macro Recorder in VW. It has been requested many times. For geometry, you can draw shapes in a new file, then use menu File > Export > Export Script.... This will save a VectorScript file to disk. Using a text editor, you can extract the geometry calls to your objects and substitute any or all of the numerical parameters for variables which you can control in your script. This is a shortcut to building a script, but not the same as a Macro Recorder. If you have any questions about this, holler back. Raymond
  3. Hello David, I found constants for the Slab Tool (-248) and the Wall End Cap Tool (-355). I did not find constants for the Door or Window tools, but those two can be called with CallToolByName() or SetToolByName(), as Pat mentioned. Raymond
  4. In my first post-college job, some 40+ years ago, I chose to learn Pascal over Fortran to complete an assignment. I have never looked back. I am amazed that after all these years I still use Pascal as a productive tool. Pascal is like my favorite pair of jeans – they still fit, so I still wear them. I've learned and used other languages and see their benefits, but Pascal will always be closest to my heart. Thank you Niklaus Wirth. Bon Voyage.
  5. 12255 is "SetupDialogC", and is found in the dialog event loop. It is an event that is passed to your dialog event loop once before the dialog returns any of your events, i.e., before you do anything. This event is where you perform all of your setup actions. There is also 12256 for "SetDownDialogC", which is called once after the dialog returns all of your events, i.e., after you press the OK or Cancel buttons. HTH, Raymond
  6. Hi @BillW, I have tried GetCurrentPlanarRefID with and without objects on a working plane that I just set, and still get no meaningful response from it. I am very familiar with all of the other calls you cited, and they perform exactly as expected when used. I really just want find out how GetCurrentPlanarRefID is supposed to be used and under what conditions it operates. Thank you kindly for your reply, Raymond
  7. Without breaking out your high school Geometry books, you can use vectors to keep track of where you are and where you want to go. Without knowing where you reference your base part I cannot give you exact code for your problem, but it should look something like this: # rotate 2D vector V by Ang degrees def RotVec(V, Ang): return vs.Ang2Vec(vs.Vec2Ang(V)+Ang, vs.Norm(V)) # add vectors A and B def VecAdd (A, B): return tuple(map(sum, zip(A, B))) # subtract vector B from A def VecSub (A, B): return tuple(map(lambda x, y: x - y, A, B)) ... DispV = VecSub(LRcornerPt, InsertionPt) % displacement vector NextInsPt = VecAdd(InsertionPt, RotVec(DispV, PartRotation)) where PartRotation is vs.GetSymRot(symHd) for symbols, or an angle value you keep track of programmatically; and the vector values are tuples of (X, Y). I have not tested this, so proceed with caution. If you need more help, write back or contact me offline. I'd be more than happy to help. Raymond
  8. When I execute GetCurrentPlanarRefID on a design layer it returns "1" if I am drawing on the Layer Plane or any 3D Working Plane I set. If I change to the Screen Plane it returns '0'. Inside a symbol's 2D side it returns "0", and on the 3D side it returns "-1". Inside an Extrude it returns "-1". On a Sheet Layer it returns "0". I understand the Layer Plane is refID = 1, and the Screen Plane is refID = 0, while Working Planes have other integer values for the refID. I cannot get it to recognize any Working Plane I set in a drawing. Am I missing something, or does this command not do anything I can use? The documentation says: "Return the current plane ref ID. This could be any plane: a working plane, screen plane (0), ground plane of a container, or any arbitrary plane." If anyone has been able to use this command to identify planes other than the Screen or Layer planes, I would really like to hear from you. TIA, Raymond
  9. Hi Jayme, It may not be the answer you wanted, but it sounds like you are on the right path. Another thing to evaluate, how fast does CopySymbol() work if your reference file is open all the time? I don't know what your system configuration is, but consider opening the reference file when you launch VW and leave it open for the drafting session. If it works, and your system doesn't slow down, it may keep you from splitting the symbol file right now. Just a thought. All the best, Raymond
  10. Hello @Jayme McColgan, First question, did you convert your reference file to VW 2024 format? I would expect this to give you the best chance for success. If you have converted it and your code still runs slowly, I would copy some symbols into a much smaller temporary file and try your code again. If it's still slow, then it's not the reference file's size. Perhaps it's a drive, or network problem. Try copying the file to your computer and try again. Does it run faster when the file is local? If pulling symbols from a much smaller file speeds things up significantly, then I would find a way to partition your non-partitionable file into two or more smaller files. Split it alphabetically and you can easily code your symbol calls to address the correct source file using the symbol's name to determine the source file. Of course there are many ways to approach the overall problem. I hope you find one that works well for you. Raymond
  11. Hello, @halfcoupler. Your script seems to work in VW 2024, and 2023. If only one object is selected the OIP updates. If multiple objects are selected, then, yes, the OIP does not update the Class popup menu and displays the old setting. If you have multiple objects selected, do you want to apply the new class name to all of the selected objects? If so, try this script: PROCEDURE Set_A_Class; { Change the class name of all selected objects that are on editable layers. } CONST kNewClass = 'MyClass-Pink_Flamingo'; function ApplyClass(H :Handle) :Boolean; Begin SetClass(H, kNewClass); SetSelect(H); { Resets OIP } End; BEGIN ForEachObjectInLayer(ApplyClass, 3, 0, 4); { Visible/Selected, Shallow, Editable } SysBeep; { make noise when done } END; RUN(Set_A_Class); To assign other class names, change the constant "kNewClass". The ForeEachObjectInLayer() function loops through every object that meets the conditions specified by the three numbers shown in the call. In this case it looks for Visible and Selected objects (1+2), does not go inside Groups or other containers, or Shallow (0), and works across Editable Layers (4). If you need more information on this and similar ForEachObject functions, check out the Developer Wiki and Function Reference Links in the blue bar shown at the top of this page. HTH, Raymond
  12. @Pat Stanford, It's this button: I didn't know either until I floated the cursor across the icons looking for a clue. Luckily one popped up. Raymond
  13. @Juliensv, Are you wanting the value to use in a worksheet, or just in a script? For accessing the length in a script, here's an example that shows the exact length in document units but w/o the units string displayed. PROCEDURE xxx; { Show the length of a selected dimension object. } { 10 Nov 2023 - Raymond J Mullin } VAR H :Handle; B :Boolean; P1, P2 :Vector; BEGIN H := FSActLayer; if (GetTypeN(H) = 63) then begin { Dimension object } B := GetObjectVariablePoint(H, 13, P1.x, P1.y, P1.z); { point 1 } B := GetObjectVariablePoint(H, 14, P2.x, P2.y, P2.z); { point 2 } AlrtDialog(concat('Dimension Length = ', Norm(P2-P1))); { display length } end { if } else AlrtDialog('Selected object is not a DIMENSION object.'); END; Run(xxx); If you want to control the number of decimals displayed in the answer, use the Num2Str() function around the Norm() function, or if you want the answer formatted using the current document units, use the Num2StrF() function. Lastly, if you want the answer for use in a Worksheet function, a some lines will need to be added and removed. HTH, Raymond
  14. Hello Peter, Reshaper will let you set the 3D view relative to the selected 3D Object. Top, Front, Left, Iso views top and bottom. And you can rotate the view around the primary axes relative to your current view. I believe you have a copy of Reshaper. Let me know if it needs updating. Raymond
  15. Also, FWIW, Entered in Group which is also listed as 6756 might be 6755 as defined on the next line: varGetEnteredGroupHandle = 6755, // Handle read - Get the Handle of the current opened for edit group in VW document. BUT, is it? I have not used this pref yet, so I can't tell you exactly how it's supposed to work, but it looks like GetPref(6755) returns returns FALSE if you are on a Design or Sheet Layer, and TRUE if you are inside a GROUP, a Symbol, a Polyline Profile, an Extrude, i.e., inside a container object – BUT – if you enter a GROUP that's inside a Symbol Definition, it returns FALSE. Not sure I understand this last part. And here if gets weirder, if you are inside a Group inside another Group inside a Symbol Def, it returns TRUE. It's Alice Through the Looking Glass trying to find Waldo. This is all off the cuff, and doesn't answer anybody's question at the moment, so enjoy the rabbit hole, all ye who enter. Raymond
  16. God bless Carlotta !!! 😇
  17. Yes, I would build a list of class names and their replacements, then iterate through the list. There may be a more elegant approach, but none comes to mind. There are many ways to build the list, and that may be where you achieve elegance. You'll want to restructure the example program to make the main loop into a procedure that you call for each item in your list, passing it the new and old class names. ForEachObjectInList() will do most of the heavy lifting. If you have any questions about the existing example, please write back. All the best, Raymond
  18. Hi @Sam Jones, It is true, Python has its quirks, but so does the VS language. You've learned many of them over the years. In all, Python has more upsides than down. As you are very comfortable with VS, I wouldn't recommend moving for the sake of moving. Unless you you need something that Python can offer, like access to external packages, or superior list management, I'd say stick with Pascal. If you ever need Python help, you still don't have to learn it, just ask and Python help will come to you. 😉 Raymond
  19. Hi @Jayme McColgan, You can also change your document units briefly to be in the units you need for the numerical drawing. Might save a bit of editing. To draw in inches, precede your drawing code with: UPI = vs.GetPrefReal(152) # save document scale vs.SetPrefReal(152, 1) # Inches And follow it with this: vs.SetPrefReal(152, UPI) # restore document scale If you set Pref152 to 25.4 you will be drawing in mm, and if you set it to 0.083333333, you will be drawing in feet, etc. HTH, Raymond
  20. @JBenghiat brings up a good point. You also have to test if a name conflict is with a Class Name or a name to another resource or object. The code I posted does not resolve that, and assumes the name in conflict is another Class Name. If you need help modifying the code, please write back, or have at it. You may modify the code above to your liking. Raymond
  21. Hello @Peter Z, If you want to use an existing name, you would need to go through the document and change all objects existing in the old class to the new (existing) class. This can be achieved with: ForEachObject() and ForEachObject(). Here is a quickly crafted script to change one class to another. USE WITH CAUTION AND ALWAYS USE ON A COPY FIRST. PROCEDURE ChangeClassNames; { Change the name of a class to a new name. If objects exist in the OLD class, then } { change the Class Name of all objects in the document, and in the symbol library, } { that have an existing class name of kOldClass to the new class name kNewClass. } { THIS SCRIPT IS VERY LIGHTLY TESTED! } { TRY ON A COPY OF YOUR FILE AND CHECK RESULTS CARFEFULLY BEFORE PROCEEDING! } { 30 OCT 2023 — RAYMOND MULLIN } CONST kOldClass = 'oldClassName'; kNewClass = 'newClassName'; CR = c_h_r(13); { *** remove "_" characters before use *** } VAR LCnt, SCnt :Longint; procedure ChangeClass(H :Handle); { Change the class name to class kNewClass. } Begin SetClass(H, kNewClass); LCnt := LCnt + 1; End; { ChangeClass } function ChangeClass1(H :Handle) :Boolean; { Change the class name of any object that has a class of kOldClass to class kNewClass. } Begin if (GetClass(H) = kOldClass) then begin SetClass(H, kNewClass); SCnt := SCnt + 1; end; { if } End; { ChangeClass1 } BEGIN LCnt := 0; { count of changed objects on layers } SCnt := 0; { count of changed objects in symbols } if (GetObject(kNewClass) = nil) then { if New Class Name does not exist } RenameClass(kOldClass, kNewClass) else begin { if New Class Name exists } ForEachObject(ChangeClass, (C=kOldClass)); { change class name of all objects placed in document } ForEachObjectInList(ChangeClass1, 0, 2, FSymDef); { change class name of all objects in SymDef list } AlrtDialog(concat('# of objects on layers changed: ', LCnt, CR, '# of objects in symbols changed: ', SCnt, CR, 'Total objects changed: ', LCnt + SCnt)); end; { if / else } {DelClass(kOldClass);} { delete Old Class Name when done – OPTIONAL } SysBeep; { make noise when done } END; Run(ChangeClassNames); HTH, Raymond
  22. Hello @Peter Z, Yes, you can use RenameClass(oldname, newname). The real work in your question is the interface. Probably the simplest way would be to create a text file with a list of old and new names then write a script to read and process it. Not sexy but not too hard to code. A fancy dialog based UI will be 99% dialog programming, and 1% code execution. Unless this is a chore that you expect to repeat a lot, KISS. Raymond
  23. You can use the ForEachObject family of calls. There are four – ForEachObject(), ForEachObjectAtPoint(), ForEachObjectInLayer(), and ForEachObjectInList(). ForEachObject() takes criteria statements. The others work across Layers, with Lists, or at a Point. They take a little time to get proficient with them, but they are very powerful. If you search the forum for these commands you should find quite a few examples. Raymond
×
×
  • Create New...