Jump to content

MullinRJ

Member
  • Posts

    2,007
  • Joined

  • Last visited

Everything posted by MullinRJ

  1. It would be difficult to guess w/o seeing the dialog code. You can strip out your handler code just send the creation and element placement calls. Raymond
  2. Mr. Do, Your problem is not "really" a bug, but rather a limitation that is constraining one of your radii. When you create a Polyline with two consecutive "curve" points, imagine there is an invisible point halfway between them. The first arc you define doesn't see that "voodoo" point because it (pt. 2) is surrounded by corner points (pts. 1 & 3). Once point 2 is converted to an Arc Vertex, when you then try to change point 3 to an Arc Vertex you will encounter the "invisible" point. In your example, it exists at (300, -528.5), which is halfway between points 2 & 3 of the starting 2D polygon. The way to overcome this obstacle is to place a Corner Point between your two fillet points such that it allows the full radius of each to be realized. The algebra is more than I care to address at this time, but if you run your script with the following mods I made, it will work. PROCEDURE test; VAR h1 : handle; x, y, vertexType, vertexRadius : real; BEGIN Poly3D (5, -5, 0, 300, -300, 0, 300, -757, 0, 5, -462, 0); h1 := ConvertToPolyline (LNewObj); InsertVertex(h1, 300, -390, 3, 0, 0); { this line helps } SetPolylineVertex (h1, 2, 300, -300, 3, 140, true); SetPolylineVertex (h1, 4, 300, -757, 3, 140, true); { pt 3 becomes pt 4 } END; Run (test); Welcome to the world of polyline editing. Raymond
  3. Mr. Do, Yes, it is broken, or better yet, never worked. I've been playing with it for a day now (since your previous thread) and from VW 2010, when it was introduced, to VW 2015 it never worked. The Z components are always 0. GetPt3D() seems to be equally afflicted. To get 3D points interactively try: ********* procedure Get3DPt(var P :Vector); Begin CallTool(-316); { 3D Locus tool } GetLocus3D(LActLayer, P.x, P.y, P.z); DelObject(LActLayer); End; { Get3DPt } ... BEGIN Get3DPt(P1); Get3DPt(P2); ... ********* This won't give you the rubberband effect of GetLine3D, but it will work with 2 clicks. You can thank Gerard Jonker for suggesting this method years ago. Raymond
  4. Yes, you can create a 1-line menu command with this: SetPref(1099, not GetPref(1099)); Then add the command to your workspace(s) and assign a HotKey to it. If you're new to this level of scripting, read Robert Anderson's post here. Raymond
  5. Jon, You could create a group with one object then add new objects to it with SetParent(). Or, deselect objects from your selection list with SetDSelect(), then use GROUP to group the remaining selected objects. HTH, Raymond
  6. Mikaymikz, The call you want is: NewField(RecordName, FieldName, Num2Str(0, IntVal), 1, 0); { Integer } This will create a new field or or overwrite an existing one. Different options will create different data types. HTH, Raymond
  7. Pat, Thanks for posting. This is a great example of how to use scripting, records and worksheets together. I'd love it if someday the worksheet could be made to run attached scripts. I added a few lines at the front to have the script create the required record format if it doesn't exist, so the user doesn't have to. I also shortened the If/Else statement. Hope you don't mind. Raymond Procedure Rect_Dims_to_Record; {Attaches a record to any selected Rectangles that do not have the record attached} {and stores the rectangle height and width into that record.} {Must be rerun any time the dimensions of a rectangel change.} {Written to provde the hgiht and withs of a rectangle in a form} {accessible in a worksheet.} {Sept. 19, 2014} {? 2014, Coviana, Inc - Pat Stanford pat@coviana.com} {Licensed under the GNU Lesser General Public License} {Use at your own risk. Look both ways before crossing.} {Due to the risk of water pollution, use this, and all, scripts} {at least 100 meters from natural waterways. } { Oct. 06, 2014 - R. Mullin } { Added code to create the required record format if it does not exist. } { This removes the need for the user to create it before running this script. } { Shortened the WHILE/IF loop by removing ELSE clause and getting the } { "NEXT Selected OBJect" outside the IF statement. } Const {Change the constants here to reflect the Record Format and Field Names you are using} RecName = 'RectRecord'; WidthField = 'RWidth'; HeightField = 'RHeight'; Var RectHandle: Handle; {Handle to the current object we are working with} FullHeight, FullWidth : String; {Need to use a single variable to hold the rec.field} Begin { create record format if it does not exist. } if (GetObject(RecName) = nil) then begin NewField(RecName, WidthField, '0', 3, 0); NewField(RecName, HeightField, '0', 3, 0); end; { if } RectHandle := FSActLayer; {Get the first selected object} While (RectHandle <> Nil) do {Repeat until all selected objects have been handled} Begin If (GetType(RectHandle) = 3) then {Check if object is a rectangle} Begin {If it is a rectangle then...} SetRecord(RectHandle,RecName); {Make sure the record is attached} SetRField(RectHandle, RecName, WidthField, Num2StrF(HWidth(RectHandle))); {set width} SetRField(RectHandle, RecName, HeightField, Num2StrF(HHeight(RectHandle))); {set Height} End; { if } RectHandle:=NextSObj(RectHandle); {Move on the the next selected object} End; { While } End; Run(Rect_Dims_to_Record);
  8. If you use absolute paths, you should be able to nest your includes several files deep. I've succeeded nesting 4 levels deep and even get it to work across a network, PC to Mac. Keep playing with it. It should work. At one point I did have to add extra backslashes to the front of the volume name of the Mac address when running from the PC. {$Include \\\minimac\etc. } Not sure if this is pertinent to PC addresses running across a PC network. Raymond
  9. In VW 2013 and earlier, you can also toggle it manually under menu Tools > Scripts > VS Compiler Mode. If you intend to toggle it often, use the SetPref() route. Raymond
  10. There will be, Michael, when "we" (meaning "you") finish writing them. ;-) Keep up the good work. Raymond
  11. Alberto, ???The code I posted assumes the VP is the only object selected on the active layer and you entered it by double clicking on the VP. If you entered the VP some other way, then you're right, it may not work. BUT, if you already have a handle to the VP, then you don't need to use FSActlayer, just use your VP handle. The rest is elementary. ???As long as you have something that works, that is good. However, I don't see how the script you posted will work since your handle to a list, "h", is uninitialized when you call ForEachObjectInList(). Raymond
  12. At 1:1 scale the smallest line width in VW is 1 mil, which equals 0.001". It's been this way since before 1990. What unit base and layer scale are you using? Raymond
  13. Try this: ???VPHnd := FSActLayer;????{ VP Handle } ???if (GetTypeN(VPHnd) = 122) then begin????????{ VPHnd is a ViewPort } ??????H := FInGroup(GetVPGroup(VPHnd, 2));????{ 1st object in Annotations Group } ??????if not Selected(H) then H := NextSObj(H);??{ 1st selected object in Annotations Group } ???end ???else H := nil; "H" will hold the answer. If no object in the Annotations Group is selected, or VPHnd is not a ViewPort, "H" will be NIL. Raymond
  14. Nig, ???Have you seen this thread? http://techboard.vectorworks.net/ubbthreads.php?ubb=showflat&Number=93218#Post93218 Raymond
  15. Seth, ???When in doubt, when the pink hammer doesn't work, use the purple hammer. Since Python is practically brand new, it is difficult to debug since the confidence level for the functionality and side effects of each command is low (at least in my opinion). To see if your (un)expected output is a function of your approach or of Python's implementation, I rewrote your code using VectorScript. ???It appears there is a difference in how Python and VS function. Please go over my VS below and verify that I translated your code correctly. If I did, there is an error in Python and not in your approach. With more than 2100 commands, it will take a goodly while to evaluate the entire Python API to the same level as the VS API. Raymond PROCEDURE xxx; CONST CR = chr(13); VAR I, color :Integer; origin :Vector; procedure makeText(a, b, i :Integer); Begin MoveTo(a, b); CreateText(Concat('origin:', Num2Str(1, i), ', ', Num2Str(1, i), CR, 'X:', Num2Str(1, a), ' Y:', Num2Str(1, b))); End; { makeText } procedure makePoints(i :Integer); Begin SetOriginAbsolute(i, i); makeText(-1, 1, i); makeText(0, 1, i); makeText(1, 1, i); makeText(-1, 0, i); makeText(0, 0, i); makeText(1, 0, i); makeText(-1, -1, i); makeText(0, -1, i); makeText(1, -1, i); End; { makePoints } BEGIN GetOrigin(origin.x, origin.y); PushAttrs; TextFont(GetFontID('Arial')); TextJust(2); TextVerticalAlign(3); FillPat(0); Opacity(100); PenSize(5); PenPat(1); RGBToColorIndex(1, 1, 1, color); PenFore(color); PenBack(color); TextSize(6); for I := 0 to 5 do makePoints(I); SetOriginAbsolute(origin.x, origin.y); PopAttrs; SetZoom(50); END; Run(xxx);
  16. Hello Uwe, ???There is no easy way to make that comparison. I think it would be better if you structured your script to make comparisons guided by object type, since nearly every type has different attributes to compare. Some attributes are the same, like line weight and fill colors, but others differ in a broad way, like polygons have vertices but ovals do not. The 3D types will be the most difficult to test. I suggest you set up a case statement based on ObjectType and custom tailor each comparison that way. ObjTyp1 := GetTypeN(Halt); ObjTyp2 := GetTypeN(Hneu); CASE ???2: begin?? { Line } ?????????{ compare endpoints } ?????????{ compare line weight } ?????????{ compare line color } ?????????{ compare line style } ?????????{ compare plane - Screen, Layer, 3D } ???????end;???{ 2-Line } ???3: begin???{ Rect } ?????????{ compare BBox } ?????????{ compare rotation } ?????????{ compare line weight } ?????????{ compare line color } ?????????{ compare line style } ?????????{ compare fill color } ?????????{ compare fill pattern } ?????????{ compare plane } ???????end;???{ 3-Rect } ???{ etc. } END;???{ case } ???This is not a script you will finish in a day, or a week, but you can keep adding to it as you need to check different types. You can also start by checking basic properties, like BBox, Center, and Rotation, and expand your checking later to include vertex positions and vertex order. ???As you can see, this will be a very complicated script if you check everything. But depending on your needs, you may not have to compare everything or every object type which will simplify things considerably. ???All of this said, you should search a little on the web. One of the 3rd Party Developers has a compare utility for sale, but I've forgotten which one (I think it's VectorBits, but I'm guessing). I seriously doubt you can write your own for less than you can buy one today. Good luck, Raymond
  17. Who, ???SetFocusOnItem() is described in the VSFR as "Sets the keyboard input focus on the specified item.", which doesn't say much, but it looks like it's used with entering text into a dialog; so it needs to be executed from the event loop that controls the dialog when it is running and not in the dialog definition code. ???If you add this overly SIMPLISTIC event loop procedure to your code: ??????procedure eventLoop(var item: Longint; data :Longint); ??????Begin ?????????SetFocusOnItem (id, 7);???{ do this on every event } ??????End;???{ eventLoop } AND, call the event loop by changing your RunLayoutDialog() statement to this: ??????result := RunLayoutDialog (id, eventLoop); you might notice that every time you generate an event in your dialog your checkbox will highlight, and if you hit the Space Bar repeatedly your checkbox will toggle. ???I'm pretty sure this is not what your are trying to achieve, but the command will do something if it is executed in the right place. Describe your desires in more detail and you should get better responses to your problem. Raymond
  18. Sam, ???If you create a STRUCTURE to represent the column fields of your 2D array, then you can create a 1D array of the structure which is sortable. Here's an example. Note, you can have field names the same as your variable names, but if that's confusing, then don't do it. HTH, Raymond ***** PROCEDURE SortStructureExample; { Sample code for sorting an array of a STRUCTURE. } { Gather X, Y, & Rotation of selected symbols and sort them by their Y value. } { Place multiple symbols on a design layer, select them, and run script. } { Symbols will highlight one at a time from lowest to highest Y value. } { 30 Nov 2013 - Raymond J Mullin } TYPE ???XYR = STRUCTURE ??????h :Handle;??????{ 1st field } ??????x, y, r :Real;???{ 2nd, 3rd & 4th fields } ???end;???{ XYR } VAR ???H :Handle; ???I, CntSel :Integer; ???SymPos :DynArray [] of XYR; BEGIN ???CntSel := NumSelectedObjects; ???Allocate SymPos [1..CntSel]; ???I := 0; ???H := FSActLayer; ???while (H <> nil) do begin ??????if (GetTypeN(H) = 15) then begin???{ symbol instance } ?????????I := I + 1; ?????????GetSymLoc(H, SymPos.x, SymPos.y); ?????????SymPos.r := GetSymRot(H); ?????????SymPos.h := H; ?????????H := NextSObj(H); ??????end;???{ if } ???end;???{ while } ???SortArray(SymPos, I, 3);???{ I = # of selected symbols, 3 = Y field } ???{ Highlight each symbol from lowest to highest Y value. } ???for I := 1 to CntSel do begin ??????DSelectAll; ??????SetSelect(SymPos.h); ??????wait(1); ??????RedrawAll; ???end;???{ for } ???SysBeep; END; Run(SortStructureExample);
  19. I believe that's the Holy Grail for all of Programming. For me, IMPLEMENTED means fully checked out and documented. Just because something compiles doesn't mean it is fully functional. Even released routines can contain bugs. Unreleased routines are expected to have bugs until proven otherwise. The VWPluginLibraryRoutines.p file is a proving ground for NEW routines. I, for one, am happy the engineers put out their preliminary work before all the nitty gritty details are in place. It usually takes a lot longer to produce formal documentation and thoroughly test out an idea than to write the idea down. I'm not saying you shouldn't use the unreleased calls. On the contrary, use them and prove to yourself that they do work, and when you find a bug or a shortcoming, send in a report to get it resolved. Since I'm not an NV employee, these are only my opinions and do not reflect any policies or procedures for implementing or releasing new VS routines. That said, I believe the current system works well. If you're like me and these version numbers are of interest to you, keep a list. I do. Raymond
  20. Many VectorScript functions exist in VW before they are released in the VectorScript Function Reference (VSFR) or on the Developer's site. They can be found in a file in the user's Plug-ins folder with the name "VWPluginLibraryRoutines.p". In the past, this file has acted as a proving ground for new functions before they are documented. I believe the release version shown with each function is the version that function's documentation was moved into the public domain. Likewise, on the other end of a function's life, you will see them marked with an OBSOLETE label, but you will also find that obsolete functions will work several versions after being marked as such. This is a courtesy given to scripters and developers by the NV Staff to allow time to rewrite existing code with newer functions replacing the obsolete ones. In actuality an accurate function list would have four versions defining its existence: First Compile Version Release Version Obsolete Version Last Compile Version The versions shown on the Developer's site and in the VSFR are the "Release Version" and the "Obsolete Version". Please don't ask to have this changed. It took a lot of work to make the currently shown versions consistent. Raymond
  21. It works on my machine. How about adding a signature? It's hard to guess how you are working. And while you're at it, how about some relevant details about your problem? Are you running a script? A PIO? A menu command? Usually I skip questions like this because they are too vague. You just caught me in a good mood. :-) Raymond
  22. Wouter, ???I'm not sure about the Lofting part of your problem, but creating an OVAL on a 3D plane can be done as follows. Oval(u4.x+D1x/2, u4.y+D1x/2, u4.x-D1x/2, u4.y-D1x/2); SetObjectVariableBoo(LNewObj, 1160, False);?????????????{ False = LayerPlane } boo := SetEntityMatrix(LNewObj,???PlaneCenX, PlaneCenY, PlaneCenZ,???PlaneRotX, PlaneRotY, PlaneRotZ); ???SetObjectVariableBoo() will force the Oval to be on the Layer Plane with the center at u4. SetEntityMatrix() will move it to a 3D plane whose center is at PlaneCenXYZ with the plane rotated by PlaneRotXYZ. The oval's center will be at u4 in the relative coordinates of the new plane. ???This doesn't answer your question fully about Lofting, but it does define how to move 2D objects onto an arbitrary 3D plane, except for 2D Symbols. (The NV engineers do not follow the same rules when they create the Entity Matrix for a planar 2D Symbol.) ???I'll leave it to you to try to do the Loft at this point. Please write back and let us know if it works. ???One caveat - if the User Origin is shifted, so will be the 3D plane's origin. It may be easiest to reset the User Origin, create your planar object, then reshift the User Origin. Raymond
  23. Yes. I did, but only once. I made some other changes and saved them, then pasted the vs.AlrtDialog() statement back and it worked. After that I couldn't make it fail, even in a new file. Perhaps restarting VW might help it fail again. It's an intermittent bug, at best. Did you file? Raymond
×
×
  • Create New...