User Tools

Site Tools


snapping_in_pcb

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
snapping_in_pcb [2018/06/03 19:06]
cparker [Details]
snapping_in_pcb [2018/07/26 15:04]
cparker [Discussion]
Line 16: Line 16:
  
 ===== Proposed System ===== ===== Proposed System =====
-Presently implemented ​in the home/​cparker/​snapping_overhaul branch.+Implemented ​in the home/​cparker/​snapping_overhaul branch. 
 ====Overview==== ====Overview====
-The snapping code is presently ​located in two places: snap.[c,h] and crosshair.c. snap.[c,h] defines several general types that are used to do the snapping. crosshair.c is where the snapping actually occurs and is where all of the snapping functions are implemented.+Snapping is initiated by moving the mouse. The paths for each HID are different, but they ultimately end up calling crosshair.c:​MoveCrosshairAbsolute. This function computes a new location for the crosshair, and updates the X, Y location in the global crosshair structure. The computing a new location part is where the snapping happens. MoveCrosshairAbsolute is triggered by mouse events, so, it can potentially be called very frequently. Consequently,​ this function should execute very quickly. 
 + 
 +MoveCrosshairAbsolute calculates the new crosshair position by checking for snaps, checking that the crosshair is inside of it's boundaries, and then enforcing DRC. Checking for snaps occurs by iterating through a list of functions, each of which looks for a particular type of object: lines, arcs, elements, pins, etc. The first function to find an object provides the coordinates that the crosshair snaps to. By changing the order of functions in the list, different types of objects can be given different priorities. Both the function that does the iterating and the snapping list can be changed dynamically so that different snapping policies can be implemented depending on the software context. 
 + 
 +====Details==== 
 +The snapping code is located in two places: snap.[c,h] and crosshair.c. snap.[c,h] defines several general types that are used as infrastructure for the snapping. crosshair.c is where the snapping actually occurs and is where all of the snapping functions are implemented.
  
 There are three new types in snap.[c,​h]: ​ There are three new types in snap.[c,​h]: ​
Line 35: Line 41:
 Both of the crosshair items are implemented as pointers so that they can be changed dynamically. You could, for example, change the snap list when you go into line drawing mode so that you don't snap to elements or other lines, or do so in a different order. Similarly, you could change the snapping function to one that snaps based on which item is closest as opposed to which has the highest priority. Both of the crosshair items are implemented as pointers so that they can be changed dynamically. You could, for example, change the snap list when you go into line drawing mode so that you don't snap to elements or other lines, or do so in a different order. Similarly, you could change the snapping function to one that snaps based on which item is closest as opposed to which has the highest priority.
  
- +====Data Structures====
-====Details==== +
 In a nod to the gobject/​glib folks, I've tried to adopt some similar naming conventions for functions. In a nod to the gobject/​glib folks, I've tried to adopt some similar naming conventions for functions.
  
Line 77: Line 81:
 One thing to note: there is a feature, I think it's called 'Auto Enforce DRC Clearance'​ in the settings menu. It used to be implemented at the end of the ''​FitCrosshairIntoGrid''​ function that was previously responsible for the snapping. This has been moved into ''​MoveCrosshairAbsolute''​ until a better home can be found for it. I don't think this really belongs as part of the crosshair subsystem. One thing to note: there is a feature, I think it's called 'Auto Enforce DRC Clearance'​ in the settings menu. It used to be implemented at the end of the ''​FitCrosshairIntoGrid''​ function that was previously responsible for the snapping. This has been moved into ''​MoveCrosshairAbsolute''​ until a better home can be found for it. I don't think this really belongs as part of the crosshair subsystem.
  
-===Discussion=== +====Adding Snaps====
-One thing I'm on the fence about is if the snapping functions should get a pointer to the SnapSpecType they were called from. Presently, the functions answer the question: "is there something of this type under the cursor that can be snapped to?". To answer that question, the SnapSpecType data isn't required, and so presently it's not provided. However, if this were to become more sophisticated in the future, it might become necessary. +
- +
-===TODO List=== +
-  * Configuration actions +
-  * snap-to-the-closest-object function +
-  * snapping preferences saving +
-  * sub-snaps? (lines, line endpoints, midpoints... ) +
-  * lesstif config page +
-  * tests +
- +
-===Adding Snaps=== +
 TODO: TEST THIS! TODO: TEST THIS!
  
 Under this configuration,​ it is fairly easy to add snaps or change the snapping behavior using plugins. Let's examine how that could work with an example. Let's change how the element snapping works. Presently, it snaps to the location of the element mark. Let's snap to the center of the bounding box instead. Under this configuration,​ it is fairly easy to add snaps or change the snapping behavior using plugins. Let's examine how that could work with an example. Let's change how the element snapping works. Presently, it snaps to the location of the element mark. Let's snap to the center of the bounding box instead.
  
-First, get the plugin template from [pcb_developer_introduction_2]. In a real plugin, you would probably want to write some actions to enable and disable your features, but, for the sake of this example, we'll skip that. So, delete that stuff. Then, let's grab the existing code for snapping to elements out of crosshair.c,​ and copy it into the plugin file. There are two parts, the snapping function, and the ''​SnapSpecType''​ definition. Here they are (more or less). The snapping function should be fairly easy to read:+First, get the plugin template from [[geda:pcb_developer_introduction_2]]. In a real plugin, you would probably want to write some actions to enable and disable your features, but, for the sake of this example, we'll skip that. So, delete that stuff. Then, let's grab the existing code for snapping to elements out of crosshair.c,​ and copy it into the plugin file. There are two parts, the snapping function, and the ''​SnapSpecType''​ definition. Here they are (more or less). The snapping function should be fairly easy to read:
  
 <code C> <code C>
Line 204: Line 196:
  
 Congrats! You've extended pcb with a new snap. You could do something similar to replace the snapping function. Congrats! You've extended pcb with a new snap. You could do something similar to replace the snapping function.
 +
 +=====Discussion=====
 +This section is for ideas and discussion regarding things related to the snapping implementation.
 +
 +==Who Does the Snapping==
 +Regarding the crosshair integration,​ there is a question in my mind about algorithm. Should the crosshair be responsible for the snapping? Presently the procedure is...
 +  * the mouse is moved 
 +  * a function is called to move the crosshair to the mouse location
 +  * the crosshair checks underneath it for something to snap to
 +  * if it finds something, it adjust the coordinates to the location of the object
 +  * it moves the crosshair to the new location.
 +Perhaps is should be that the HID calls the snapping, and the crosshair just goes where it's told:
 +  * the mouse is moved
 +  * the a snap is searched for underneath the mouse location
 +  * if a snappable object is found, the coordinates are updated
 +  * the crosshair is told to move to the new location
 +
 +==Need to Know==
 +One thing I'm on the fence about is if the snapping functions should get a pointer to the SnapSpecType they were called from. Presently, the functions answer the question: "is there something of this type under the cursor that can be snapped to?". To answer that question, the SnapSpecType data isn't required, and so presently it's not provided. However, if this were to become more sophisticated in the future, it might become necessary.
 +
 +==Snapping Modifiers==
 +A very nice feature would be if the user could press a mod key to change the snapping behavior. Perhaps the cursor only snaps to grid points normally, and then starts snapping to everything else when "​alt"​ is held.
 +
 +There are several places where this kind of behavior could be implemented. The basic idea behind them all is that you would have a second ''​SnapList''​ that was applied to the other condition.
 +  1. In the search_snaps function. It could check in with the gui to see if the modifier is active, and then select a ''​SnapList''​ to search.
 +  2. The crosshair could do the same thing before it calls the search_snaps,​ and pass the appropriate list to the search function.
 +  3. The gui could control it, watch the modifier key and change the active SnapList when the state of the key changes.
 +  4. A plugin can actually be implemented to do this. Since plugins can access the gtk structures, a plugin could install a listener function to listen for modifier key strokes, and update the crosshair snap list accordingly.
 +
 +Option 4 is the most modular, and I did write this infrastructure so that plugins could be used to modify the behavior. I think I'm going to try that method first. ​
 +
 +How does it work?
 +The plugin is loaded and creates it's alternate ''​SnapList''​. It can populate it from the structures that already exist in crosshair.c,​ I think, by declaring them as externs.
 +
 +==Snapping and Layers==
 +It's frequently the case that you only want to snap to objects on certain layers. What's the best way to implement this?
 +
 +Presently, SearchObjectByLocation doesn'​t have a layer parameter. It simply iterates over them all with every search. So, we would have to expose some of the lower level searching functions in order to restrict layers, or add layers as a parameter to SearchObjectByLocation. That function is called in a lot of places, so, it would be a lot of calls to have to update.
 +
 +How do I keep track of which layers I'm searching? Do I pass pointers? Layer numbers?
 +=====TODO List=====
 +  * snap based on screen distance instead of linear distance
 +  * don't snap to off-screen objects
 +  * snap-to-the-closest-object function
 +  * snapping preferences saving
 +  * sub-snaps? (lines, line endpoints, midpoints... )
 +  * lesstif config page
 +  * tests
  
 ===== Related Pages ===== ===== Related Pages =====
   * [[PCB Crosshair|PCB Crosshair]]   * [[PCB Crosshair|PCB Crosshair]]
  
snapping_in_pcb.txt · Last modified: 2019/03/21 12:50 by cparker