sketchucation logo sketchucation
    • Login
    1. Home
    2. Grays42
    3. Posts
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info
    G
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 3
    • Posts 21
    • Groups 1

    Posts

    Recent Best Controversial
    • RE: Plugin publishing questions.

      Sounds good.

      The draw step can be reversed or stopped by deleting the group the draw is writing to, but I don't have it enclosed in an operation. I can add that in. That's the only thing that really needs to be undone; I'm not really crazy about a single undo step rewriting the CNC environment variables and outputting the gcode to a file is a single step anyway that can't be reversed short of deleting the files from the filesystem.

      posted in Developers' Forum
      G
      Grays42
    • RE: Plugin publishing questions.

      I made the edits you advised. Still toying with the code; after I've done some more testing I'll submit to extension warehouse.

      posted in Developers' Forum
      G
      Grays42
    • RE: Plugin publishing questions.

      Ah, sorry. I forgot that you can attach zips to posts here.


      GPath Plugin.zip

      posted in Developers' Forum
      G
      Grays42
    • Plugin publishing questions.

      Hi Sketchucation,

      You guys helped me quite a bit last year, and after several revisions my CNC code is more or less fully functional. I never really had an interest in publishing it as it was for my own use, but if other people could benefit from it, it wouldn't be a bad idea. (It's months of work on my part and around 3,000 lines of code, including extensive unit testing.) I don't use GitHub and have just been using my Google Drive as basic version control.

      The basic function of the plugin is to convert a Sketchup Group or ComponentInstance into "gcode" necessary to cut out the piece with a CNC machine. It will work with any Group or ComponentInstance that has a single flat base and I have covered all types of intersections I can think of.

      Here's a gallery of the plugin in action (note that the lines are drawing the produced gcode after it has already been exported):

      Link Preview Image
      GPath plugin

      Discover the magic of the internet at Imgur, a community powered entertainment destination. Lift your spirits with funny jokes, trending memes, entertaining gifs, inspiring stories, viral videos, and so much more from users.

      favicon

      Imgur (imgur.com)

      Here's a zip to the current version:
      https://drive.google.com/file/d/0B22HAM7WzR-RWHluTTF5ekozdFk/edit?usp=sharing

      Here's a sample of the exported gcode:

      (Generated with Grays42_GPath)
      
      (---------- HEADER ----------)
      G90 (Absolute distance)
      G40 (Tool Radius Compensation Off)
      G20 (Inches)
      G17 (All curves are in X-Y plane)
      G94 (Inches per minute feed mode)
      M03 (Motor on)
      
      
      
      
         (---------- WORKPIECE 1 ----------)
         (---------- WORKPIECE NAME; G1 ----------)
         (Group x-y bounds; [6.000",4.000"],[8.000",6.000"])
         (Group height; 1.000")
         (Group base z; 0.000")
      
            (--- WORKPIECE 1, PATH STACK 0 ---)
            G00 X8.0940 Y6.0000 Z2.0000 F50.0000
            G00 X8.0940 Y6.0000 Z0.5000
      
            (--- WP 1, STACK 0,  z0.350" -> z0.350" ---)
               G01 X8.0940 Y6.0000 Z0.3500 F6.0000
               G01 X8.0940 Y4.0000 Z0.3500 F30.0000
               G02 X8.0000 Y3.9060 Z0.3500 I-0.0940 J-0.0000
               G01 X6.0000 Y3.9060 Z0.3500
               G02 X5.9060 Y4.0000 Z0.3500 I0.0000 J0.0940
               G01 X5.9060 Y6.0000 Z0.3500
               G02 X6.0000 Y6.0940 Z0.3500 I0.0940 J-0.0000
               G01 X8.0000 Y6.0940 Z0.3500
               G02 X8.0940 Y6.0000 Z0.3500 I0.0000 J-0.0940
      
            (--- WP 1, STACK 0,  z0.350" -> z0.200" ---)
               G01 X8.0940 Y6.0000 Z0.3500 F6.0000
               G01 X8.0940 Y4.0000 Z0.3151 F30.0000
               G02 X8.0000 Y3.9060 Z0.3125 I-0.0940 J-0.0000
               G01 X6.0000 Y3.9060 Z0.2776
               G02 X5.9060 Y4.0000 Z0.2750 I0.0000 J0.0940
               G01 X5.9060 Y6.0000 Z0.2401
               G02 X6.0000 Y6.0940 Z0.2375 I0.0940 J-0.0000
               G01 X8.0000 Y6.0940 Z0.2026
               G02 X8.0940 Y6.0000 Z0.2000 I0.0000 J-0.0940
      
            (--- WP 1, STACK 0,  z0.200" -> z0.050" ---)
               G01 X8.0940 Y6.0000 Z0.2000 F6.0000
               G01 X8.0940 Y4.0000 Z0.1651 F30.0000
               G02 X8.0000 Y3.9060 Z0.1625 I-0.0940 J-0.0000
               G01 X6.0000 Y3.9060 Z0.1276
               G02 X5.9060 Y4.0000 Z0.1250 I0.0000 J0.0940
               G01 X5.9060 Y6.0000 Z0.0901
               G02 X6.0000 Y6.0940 Z0.0875 I0.0940 J-0.0000
               G01 X8.0000 Y6.0940 Z0.0526
               G02 X8.0940 Y6.0000 Z0.0500 I0.0000 J-0.0940
      
            (--- WP 1, STACK 0,  z0.050" -> z0.050" ---)
               G01 X8.0940 Y6.0000 Z0.0500 F6.0000
               G01 X8.0940 Y4.0000 Z0.0500 F30.0000
               G02 X8.0000 Y3.9060 Z0.0500 I-0.0940 J-0.0000
               G01 X6.0000 Y3.9060 Z0.0500
               G02 X5.9060 Y4.0000 Z0.0500 I0.0000 J0.0940
               G01 X5.9060 Y6.0000 Z0.0500
               G02 X6.0000 Y6.0940 Z0.0500 I0.0940 J-0.0000
               G01 X8.0000 Y6.0940 Z0.0500
               G02 X8.0940 Y6.0000 Z0.0500 I0.0000 J-0.0940
            G00 X8.0940 Y6.0000 Z2.0000 F50.0000
      
      (WORKPIECE 1 REPORT;)
      (Workpiece feed distance; 38.3273 inches.)
      (Workpiece seek distance; 13.5754 inches.)
      
      
      (FINAL CLEANUP)
      
      (FINAL WORK RUN REPORT;)
      (Total feed distance; 38.3273 inches.)
      (Total seek distance; 13.5754 inches.)
      

      I'm posting while on lunch, so I'll follow up a bit later this evening. My question is, if I did want to go about publishing it, is there anything I need to alter in the code? Could someone who is experienced with writing and publishing plugins please take a look and offer me advice or recommendations?

      As I said, I'm fine with how it works for now--it does exactly what I want it to do for my own use. This is just for anyone else who would find benefit from my work.

      Thanks,
      Brandon

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't regroup an exploded ComponentInstance

      Thank you both! I'm working on the code more later tonight, I'll try implementing that. It sounds like exactly what I was after.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't regroup an exploded ComponentInstance

      Agh. Does that mean that in order to re-group the exploded ComponentInstance, I've got to pull construction information from every single bit of geometry and completely re-add them using the .add_face, .add_curve, etc. functions? That's quite a headache--are you sure there's no other way to drop them in?

      The problem occurs on every single ComponentInstance; I can make a component out of two lines, and the same errors occur from the code I posted above.

      I'm currently working on a workaround for now, but it would still be very useful to know how to quickly re-group; currently my workaround consists of exploding the clone and storing all of the exploded entities indefinitely until the logic is complete, then executing a cleanup routine afterward. The only problem with this approach is that I'm holding 50,000+ entities in some variables and calling .erase! on them after the whole thing is done is locking up the client for two minutes while Sketchup processes thousands of .erase! calls.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't regroup an exploded ComponentInstance

      Here is what I'm trying to do in the plugin itself:
      Sketchup.active_model.start_operation "Gcode Clones" selection.each do |s| if s.class == Sketchup::ComponentInstance then temp_instance = Sketchup.active_model.entities.add_instance(s.definition,s.transformation) loose_entities = temp_instance.explode parent = loose_entities[0].parent new_group = parent.entities.add_group(loose_entities) @workpiece_groups << new_group @workpieces << Workpiece.new(@environment,new_group) end end Sketchup.active_model.commit_operation

      Workpiece accepts a group and does all of my complicated logic.

      [edit:] Since that formatting is incredibly hard to read, here's pretty formatting of that snippet: http://i.imgur.com/Zuf2dGf.png

      posted in Developers' Forum
      G
      Grays42
    • Can't regroup an exploded ComponentInstance

      Problem Background/Context: Here's an example gallery of what I'm working with: http://imgur.com/a/Vfhjn

      I need to perform an extremely complicated set of functions on a number of ComponentInstances that only correctly work when a piece I'm working with is flat in the X-Y plane. (They are pieces of wood I'm going to cut out.) However, the components have other axes, and in order to perform the operation I have to explode the component and re-group it. I cannot quickly rewrite the process to correctly adapt to different axes. I need to use explode/group as a workaround until I have more time to rewrite everything.

      Problem: I am unable to use the existing functions to correctly explode/group. I need to be able to explode the ComponentInstance, then take all of the resulting entities and put them into a group, which I will then use with the functions I've written and delete the whole thing when I'm done.

      Here's a sample of what happens if I have a single ComponentInstance selected and try to perform the operation in the command line (trimming irrelevant output).

      ci = Sketchup.active_model.selection[0] #<Sketchup::ComponentInstance:0xbc75758> ents = ci.explode g = Sketchup.active_model.entities.add_group(ents) Error: #<ArgumentError: (eval):0:inadd_group': All Entities must have a common parent>`

      However, I can verify that all of the exploded entities do indeed have the correct parent:
      parents = {} ents.each {|ent| p = ent.parent; parents[p] = 0 unless parents.keys.include?(p); parents[p] += 1} puts parents #<Sketchup::Model:0xbca10d8>5711

      That means that of 5711 entities, all of them share a parent, but I can't get it to regroup correctly.

      The problem gets worse if I actually try to do the above within my plugin instead of just the command line: not only can I not group them because they "don't all share a parent", but if I check the parent immediately after exploding, it is not showing that the parent is a Model object; the parent of the exploded entities is the ComponentDefinition!

      So, I'm completely stuck. I'd have to rewrite a significant bit of my code to hack it to work with just open ungrouped faces, and that would completely destroy my future plans at scaling up the capabilities of the code to work with ComponentInstances and more complicated objects. Any suggestions on how I get this particular function to work?

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      Oh, hell, I'm an idiot. I understand what you mean now, and I'm not sure why it took me this long.

      Okay, I've rebuilt almost all of my functionality into its own class (class GcodeEdge in module Grays42_Gcode_Paths) that stores a single reference to the associated edge as an instance variable. All of the actual toolpath building is done by a container class, GcodeRoute, that stores a stack of GcodeEdges and never actually touches the edge entities themselves. Everthing works so far.

      That should resolve any potential conflicts. Sorry about that.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      @thomthom said:

      That's a mighty interesting find! I'll try and play with that myself.

      Thanks! Just remember: the real entity's base instance methods do not work even if you've retrieved the correct entity, only the mixin methods and data work. Calling something as simple as entityID on the real entity within onEraseEntity will throw an error, but if I've mixed in module functionality, all of the module's functions and variables work fine.

      That's given me enough to work with that I have completely solved my cleanup problem.

      @thomthom said:

      I'm still concerned about extending base class. It's so many ways there can be unforeseen trouble. I'd have to say it'd have to be last resort and the names needs to be very unique. (Remember that the API could add new methods in new releases.)

      ... I have to say - I don't quite understand how your extend module works... 😕 I thought one passed a module to #extend() - and the module methods could be added to the instance you extended. But you have a class within your GcodeEdge module.... ?

      I'm still fumbling around with module as it is, my priority right now is to get everything to work. I'm building a pretty robust unit testing suite as I go and I test every other line or so, so if I mess up the module and break something, I'll know it. The entire point of this is for personal use, I'm not focusing on release...but I don't mind future-proofing it either, if there's a way to get what I want done.

      By now we've discussed it enough that I believe you have a pretty good idea of what I'm trying to do...if you have a suggestion for a different way I should implement this so it plays nicely, I'm open to suggestions.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      I figured out a workaround! I accessed the correct entity in onEraseEntity!

      During testing, it turned out that the entityID of the entity passed into onEraseEntity in the observer is always the negative of the entityID of the erased entity, AND the real entity still exists and can execute mixin instance methods and retrieve instance data.

      In other words, if real_entity.entityID == 1923, and has an observer, then once you call real_entity.erase!, the observer calls onEntityErase(wrong_entity). I discovered through testing that, inside onEntityErase, wrong_entity.entityID == -1923.

      So...all I did was create global_hash_of_real_entities = {}, keyed by real_entity.entityID every time a real_entity is initialized, with the value being a reference to real_entity. Inside onEntityErase, you can access the pre-deleted real_entity by evaluating global_hash_of_real_entities[-1*wrong_entity.entityID].

      The only caveat is that you can't use any base methods in real_entity, they'll throw errors. However, if there's some functionality you need during the cleanup routine, you can duplicate it with a mixin method and that method will still exist during onEraseEntity.

      I got a test to produced this output:

      -----------TESTING GcodeVertex-----------
      Attempting to puts based on an instance variable of the erased entity (should NOT work);
      Attempting to puts based on an instance variable of the erased entity (SHOULD work);
      Success! Successfully retrieved instance data while in onEraseEntity.
      -----------------------------------------
      

      The second example produced a string that would only successfully trigger if the workaround entity (inside onEraseEntity) had a boolean switched to true BY an instance method in the entity passed into onEraseEntity prior to being erased. The solution does involve a class variable hash, but given a unique enough name, it shouldn't cause a problem.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      The code (very rough draft):

      module Gcode
      	class Sketchup;;Edge
      		def self.entity_id_is_gcode?(entity_id)
      			return @@gcode_edges.keys.include?(entity_id)
      		end
      		
      		def self.get_gcode_edge_by_id(entity_id)
      			return @@gcode_edges[entity_id]
      		end
      	end
      
      	module GcodeEdge
      		class Sketchup;;Edge
      			@@gcode_edges = {}
      			
      			def extend(base)
      				@is_gcode = true
      				@@gcode_edges[self.entityID] = self
      			end
      			
      			def is_gcode?
      				return false if @is_gcode.nil? or @is_gcode == false
      				return true
      			end
      			
      			def asdf
      				puts "Success! Successfully retrieved instance data while in onEraseEntity." if self.is_gcode?
      			end
      		end
      	end
      end
      

      The observer:

      module Gcode
      	class GcodeEdgeObserver < Sketchup;;EntityObserver
      		def onEraseEntity(entity)
      			puts entity.entityID #output is always the negative of the ID
      			
      			#Attempting to call on the entity actually passed to onEraseEntity
      			puts "Attempting to puts based on a class variable of the erased entity (should NOT work);"
      			entity.asdf
      			
      			#The REAL entity;
      			puts "Attempting to puts based on an instance variable of the erased entity (SHOULD work);"
      			pre_deleted_entity = Sketchup;;Edge.get_gcode_edge_by_id(-1*entity.entityID)
      			pre_deleted_entity.asdf
      
      	        end
      	end
      end
      

      The relevant lines from my unit tests (deleted anything not related):

      module Gcode
      		def self.unit_test_gcode_vertex
      			puts "-----------TESTING GcodeVertex-----------"
      			
      			p1 = Geom;;Point3d.new(0,0,0)
      			p2 = Geom;;Point3d.new(0,1,0)
      			
      			e1 = Sketchup.active_model.entities.add_edges(p1,p2)[0]
      			e1.add_observer(GcodeEdgeObserver.new)
      			puts e1.entityID
      			
      			e1.extend(GcodeEdge)
      			e1.erase!
      			puts "-----------------------------------------"
      		end
      end
      

      Calling unit_test_gcode over and over produces this output (notice the IDs!):

      -----------TESTING GcodeVertex-----------
      2069
      -2069
      Attempting to puts based on a class variable of the erased entity (should NOT work);
      Attempting to puts based on an instance variable of the erased entity (SHOULD work);
      Success! Successfully retrieved instance data while in onEraseEntity.
      -----------------------------------------
      -----------TESTING GcodeVertex-----------
      2074
      -2074
      Attempting to puts based on a class variable of the erased entity (should NOT work);
      Attempting to puts based on an instance variable of the erased entity (SHOULD work);
      Success! Successfully retrieved instance data while in onEraseEntity.
      -----------------------------------------
      -----------TESTING GcodeVertex-----------
      2079
      -2079
      Attempting to puts based on a class variable of the erased entity (should NOT work);
      Attempting to puts based on an instance variable of the erased entity (SHOULD work);
      Success! Successfully retrieved instance data while in onEraseEntity.
      -----------------------------------------
      -----------TESTING GcodeVertex-----------
      2084
      -2084
      Attempting to puts based on a class variable of the erased entity (should NOT work);
      Attempting to puts based on an instance variable of the erased entity (SHOULD work);
      Success! Successfully retrieved instance data while in onEraseEntity.
      -----------------------------------------
      -----------TESTING GcodeVertex-----------
      2089
      -2089
      Attempting to puts based on a class variable of the erased entity (should NOT work);
      Attempting to puts based on an instance variable of the erased entity (SHOULD work);
      Success! Successfully retrieved instance data while in onEraseEntity.
      -----------------------------------------
      

      So...it works! As far as I can tell, this will be a 100% consistent and reliable workaround for the fact that the wrong entity is passed into onEraseEntity.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      Ok, I understand now.

      So, as a solution, what if I put an extremely unique prefix in every public function definition in the base class extension? Would that be sufficient, or is there a more elegant way to get the functionality I want?

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      thomthom, I appreciate that, but I'm already there--I'm doing that. I'm trying to explain my issue in detail, and I'm miscommunicating.

      My difficulty is that the entity is no longer extended with the mixin when the entity is passed into onEraseEntity by an observer, and using .extend(Gcode) again inside onEraseEntity adds the methods, but not any of the data.

      coupled_edge is a mixin class method that functions correctly until the user deletes the edge. The deletion triggers the observer that I've attached to the edge, then it's supposed to execute this code. Note that all of the involved edges in this example have been extended as Gcode; the entity and the two adjoining edges.

      module Gcode
         class GcodeEdgeObserver < Sketchup;;EntityObserver
            def onEraseEntity(entity)
               entity.vertices.each do |v|
                  adjoining_edge = entity.coupled_edge(v) #throws undefined method
                  adjoining_edge.decouple_at_vertex(v)
                  #other cleanup methods here
               end
            end
         end
      end
      

      At this point, the entity passed into onEraseEntity no longer contains any mixin methods, and is just a core class with no other functions. I have tried a number of calls to the mixin methods and variables on the entity that is passed into onEraseEntity and none of them work. It is simply no longer extended at that point. Calling .extend(Gcode) on the entity within onEraseEntity gives it Gcode methods again, but none of the data.

      That's why I posted about making a subclass in the first place; everything in this thread has been an attempt to work around the onEraseEntity limitations. As it stands, I have absolutely no way to run a cleanup routine, as the necessary functions don't exist in the scope of onEraseEntity. Any suggestions for how to work around it?

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      Okay, that helps, it's good to know that it isn't just me.

      My workaround that I was working on was to store all mixin-enabled edges in a class array (not instance array) and trigger validation on all of them when any one is deleted...but that becomes incredibly expensive once the number of edges becomes high. Later on, I'll be breaking down b-splines into very small arcs with minimum error (as the cnc controller can't handle splines), and those will have on the order of hundreds of mixin-enabled arcs. If all arcs in a very large object are validated every time one of the hundreds of arcs is deleted when a single spline is deleted, it will have processing time on the order of n^2, very bad.

      I'll figure out another workaround and I'm glad it isn't just something I'm missing. I'll toy with adding functionality to the adjoining vertices and calling that. A mixin on the vertices of the deleted entity should still exist even if the mixin on the entity no longer does, right?

      And I'm only extending the base class within the namespace of my module, as we previously discussed. Does that cause conflicts? If so, what is your recommendation for adding the functionality I'm after to the base class without conflicting with other plugins?

      Also, a mostly unrelated question: is there a constructor for .extend or a preferred method for constructor-like functionality that automatically triggers once you call .extend on the base class of an instance? The .extended method in the documentation seems to only apply if the entire class is extended, not just an instance. Nevermind, defining .extend inside the mixin itself acted as a constructor when the mixin is triggered on an base class instance with .extend.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      @dan rathbun said:

      Well we cannot see all your code so...

      ... all I see is that you are extending the Array that is holding references to edge objects.
      But the observer callback is wanting to call extended methods on edge objects themselves.

      coupled_edge is an instance method for an Edge object within the module. When the Edge object is passed to onEraseEntity, it is stripped of all Gcode mixin instance functions and variables, making a custom cleanup routine impossible, as far as I can tell. The class variable array is how I'm attempting a workaround; it is not actually necessary, and in fact causes a big problem in the event that a very large number of Gcode Edge objects are present in the model.

      I'm looking for a workaround to implement my own cleanup routine in onEraseEntity (or, in general, when the Gcode Edge entity is erased) that has access to functions native to the module. That isn't possible unless the functions and/or variables in the mixin are present on the entity object that is passed to onEraseEntity. Any ideas?

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      I appreciate that, but I don't have any plans at present to release it to the public, nor would I under that naming convention. I'm just trying to fix my onEraseEntity problem.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      Okay, then...I tried using .extend, but my overall problem that prompted my restructuring of the class/subclass/module, etc., is the misbehaving of onEraseEntity() in the observer.

      Here's what my class looks like now (note that my "all_gcode_edges" workaround is still there, will change it to a class variable if I can fix my onEraseEntity problem):

      module Gcode
      	@@all_gcode_edges = [] 
      	
      	def gcode?
      		return @@all_gcode_edges.include?(self)
      	end
      
      	def to_gcode!
      		@@all_gcode_edges << self unless @@all_gcode_edges.include?(self)
      		@observer = self.add_observer(GcodeEdgeObserver.new)
      		
      		#Other stuff
      		
      	end
      
      	# lots of other methods
      
      end
      

      And currently, this is how my unit tests are building edges, although I'll find a way to make this a single line later:

      	p1 = Geom;;Point3d.new(0,0,0)
      	p2 = Geom;;Point3d.new(0,1,0)
      	e1 = Sketchup.active_model.entities.add_edges(p1,p2)[0]
      	e1.extend(Gcode)
      	e1.to_gcode!
      

      Say I have 3 gcode edges in a row, coupled together in doubly linked list form (each edge has a @previous_edge and a @next_edge class variable that stores a reference to the edge preceding or following it). The middle one, which is being observed, is erased by the user.

      In onEraseEntity(), I need to tell the other two, non-deleted edges "The edge that you were paired with is gone, decouple from it". But, I can't; when the entity is in onEraseEntity, it has lost access its module class functions.

      module Gcode
      	class GcodeEdgeObserver < Sketchup;;EntityObserver
      		def onEraseEntity(entity)
      			entity.vertices.each do |v|
      				c = entity.coupled_edge[v]
      				c.decouple_vertex(v)
      			end
      		end
      	end
      end
      

      On deletion, this throws:

      
      Error; #<NoMethodError; undefined method `coupled_edge' for #<Sketchup;;Edge;0xa16f364>>
      C;/Users/.../Plugins/Toolpath_Builder/gcode_edge_observer.rb;5;in `onEraseEntity'
      
      

      The coupled_edge method normally returns the edge coupled at a given vertex, and it works perfectly right up to the point of erasure, then when erasure occurs, the erased Gcode edge no longer has any Gcode functions; it has lost the Gcode mixin at some point prior to being passed into onEraseEntity(). Is there a way for me to trigger a cleanup method as it's being erased?

      If not, my only real option is to trigger a brute force validation for ALL gcode edges by storing references to all of them in a class variable Array. One of them gets deleted, all of them check and validate their coupled edges. Needless to say, this isn't exactly optimal, especially later, when I do things like break down b-splines into low-error arcs that could number in the hundreds or thousands.

      (For clarity, the reason I'm using linked list style references rather than just using the vertex is because multiple toolpaths might converge on the same vertex; A cnc bit will descend to a certain Z-plane, cut around the part to the same point, then descend again. The toolpath must have an unambiguous path and can't get confused if it gets to a four-way intersection.)

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      @aerilius said:

      The problem is that the SketchUp API does not mention a Sketchup::Edge.new constructor method. It is Ruby that has one (with 0 arguments) but it is not relevant/intended to be used for SketchUp. Initializing a Ruby object does not make a counterpart in SketchUp's C code, but calling SketchUp's C code functions (via add_edges) will create wrapper objects in Ruby.

      Yes, that's the wall I've hit. I'm wondering if there's any way around it.

      @aerilius said:

      I even wonder how your subclass edges can have a position and length?

      It would hypothetically, if I could draw it, as it would contain all of the parent class's methods. But since I can't draw it, I'll never know.

      @unknownuser said:

      If I understand right, you want to store data with entitities. You can either do that by keeping an external data structure (a hash with edges as keys), or by using entity attributes.

      If you need additional functionality, you can extend a Ruby object with a module:
      edge.extend(MyGCodeEdgeMixin)

      I think that's the solution I'm after. I'll try it out and respond back if it doesn't do what I need to. Before I get into that, will I be able to properly access and execute cleanup methods if the entity is deleted by the user? (Example in practice: If someone wants to delete an edge and redraw it, the two coupled edges need to decouple when the one in the middle is deleted. I've already developed the ability for the extended edges to automatically re-couple.)

      Also, it is apparent to me that I have misused "module". I was treating it as a scope definition rather than using the .extend function. I've never had to work with modules before.

      In any case, thanks for the info, and I'll give that a shot. Please ignore my code examples that will be posted shortly prior to this post; the moderator has to approve them, so they're in limbo as I type this.

      posted in Developers' Forum
      G
      Grays42
    • RE: Can't draw subclasses of Sketchup::Edge

      The code I'm talking about:

      In the class itself:

      module Gcode
      	class Sketchup;;Edge
      
      		def gcode?
      			@@all_gcode_edges = [] if @@all_gcode_edges.nil?
      			return @@all_gcode_edges.include?(self)
      		end
      		
      		def to_gcode!
      			@@all_gcode_edges = [] if @@all_gcode_edges.nil?
      			@@all_gcode_edges << self unless @@all_gcode_edges.include?(self)
      			@observer = self.add_observer(GcodeEdgeObserver.new)
      			
      			# Other stuff
      		end
      	end
      end
      
      

      In the observer:

      module Gcode
      	class GcodeEdgeObserver < Sketchup;;EntityObserver
      		def onEraseEntity(entity)
      			return unless entity.gcode? # <----this method works on the entity until this function runs on deletion, then this function returns false. I can't figure out why.
      			entity.vertices.each do |v|
      				c = entity.coupled_edge[v]
      				c.decouple_vertex(v)
      			end
      		end
      	end
      end
      
      posted in Developers' Forum
      G
      Grays42
    • 1
    • 2
    • 1 / 2