8 Replies Latest reply on Aug 25, 2016 5:45 AM by etib@rafael.co.il

    Selecting an object in an area



      I am new in developing automation in pcb env. using c# .Net


      As part of a MCAD-ECAD interface we are developing we need to give a solution for a solder mask placement in the layout.

      We get the solder mask location from the IDF file, but since the mentor IDF's importer doesn't understand this section we handle in manually.

      The object we get in the layout after import of the IDF is a route obstruct and we are changing it to solder mask area using automation using "PutFabricationLayerGfx " function.

      I have difficulties finding that route obstruct object using the coordinates I have from the IDF file.

      I need to find a way to select an object according to specific parameters: coordinates, type(RouteObstruct,Draw Object etc.) and layer.

      I can loop on all route obstruct object on a specific layer and find that object (by compering all coordinates), but I'm trying to find a function that let me query for a specif object according to the above parameters.

      I would appreciate any help in that matter.



        • 1. Re: Selecting an object in an area

          The Pick function is what you are looking for.  It can find anything inside or touching a box specified by coordinates.  Its functionality is basically "Is there any object of this kind in this area?"


          Here is an example with most of what you will need.  Vb.net, so you will need to do the conversion to C#:  (in this case you need to feed the function a PCB component object, but you could just as easily feed it the coordinates you want for minx, miny, maxx, maxy.)

          Public Function pick_route_obstructs(comp As MGCPCB.Component) As Boolean


                   Dim ok As Boolean

                   Dim minx, miny, maxx, maxy As Double

                   Dim po As MGCPCB.PlacementOutline

                   Dim pos As MGCPCB.PlacementOutlines

                   Dim ext As MGCPCB.Extrema


                   Dim robstructs As Object    'note you must use the object data type here

                   'even though there is an MGCPCB.Obstructs type, you can't use it with the

                   'pick function.  Pick function always returns an object data type,

                   'then you assign each object within the collection to the MGCPCB.Obstruct

                   'data type with the For/Each loop, as in this example with robstruct.

                   Dim robstruct As MGCPCB.Obstruct


                   ok = True


                   pos = comp.PlacementOutlines


                   For Each po In pos

                       ext = po.Extrema

                       If ext.MinX < minx Then minx = ext.MinX

                       If ext.MinY < miny Then miny = ext.MinY

                       If ext.MaxX > maxx Then maxx = ext.MaxX

                       if ext.MaxY > maxy then maxy = ext.maxy



                   robstructs = doc.Pick(minx, miny, maxx, maxy, 2, Nothing, False, True)

                   For Each robstruct In robstructs

                       Select Case robstruct.Type

                           Case -1

                               'any type

                           Case 128

                               'pad obstruct

                           Case 1

                               'plane obstruct

                           Case 4

                               'test point obstruct

                           Case 8

                               'trace obstruct

                               ok = False

                           Case 16

                               'trace and via obstruct

                               ok = False

                           Case 256

                               'tuning pattern obstruct

                           Case 32

                               'via obstruct

                               ok = False

                       End Select



                   Return ok


          End Function


          You can use the pick function with any other kind of objects that you want - vias, traces, holes, text objects, whatever. 

          • 2. Re: Selecting an object in an area

            Thank you very much Patrick. Your answer was very helpful.

            According to your answer I understand that the PICK function works with the extremum of a polygon.

            The input I have from the IDF is a collection of points that represent a polygon that I'm looking for in the layout.

            Do you have any ideas how I can use those points to find the area?

            Is there other function besides PICK that can help me in that matter?

            If not, I believe will need to find an algorithm to calculate extremum from a collection of points.


            Any help will be appreciated.



            • 3. Re: Selecting an object in an area

              Your task is a bit complicated.  There is some logic involved, and no quick and dirty answer that immediately gives you what you want.  Several things apply:


              1. The polygon are of interest may not be rectangular.  It may be L shaped or U shaped, meaning that there are points inside the extrema which are not inside the polygon.


              2. Some other polygon, such as the route obstruct you are looking for, may cross the polygon of interest but have no points inside it.  Stepping through the list of coordinates of the route obstruct may not tell you that the polygons cross each other. To know for certain that two polygons cross each other, the test which asks "Is point X inside polygon A?" has to be done both ways.  See if any points from polygon A are inside polygon B, and then if any points from polygon B are inside polygon A. If the polygons are crossing each other, one of the two cases must be true.


              3. Even though the number of route obstructs on a board is probably not a large number, you would probably prefer to not loop through all of them.  Also, because of 1 and 2 above, the loop would have to be done twice.  So let's try to do as little computing as possible, so as to not unduly inconvenience the electrons we have available.


              Here's how I'd do it:


              1. Get the extrema of the polygon from the IDF.  If you can get those points into an array, you can use something like this to find the extrema:


              Dim n, i As Integer

                       Dim ary(,) As Double

                       Dim minx, miny, maxx, maxy As Double

                       'x and y are the first element; 0 for x, 1 for y, the 2nd element is the value of the x or y


                       minx = 10000000000

                       miny = 10000000000

                       maxx = -10000000000

                       maxy = -10000000000

                       'these numbers are meaningless, just arbitrarily large; much larger than your expected coordinate range values


                       ary = get_your_points_from_idf()

                       For n = 0 To UBound(ary, 2)    'ubound(ary, 2) gets the range of the 2nd element of the array

                           If ary(0, n) < minx Then minx = ary(0, n)

                           If ary(0, n) > maxx Then maxx = ary(0, n)

                           If ary(1, n) < miny Then miny = ary(1, n)

                           If ary(1, n) > maxy Then maxy = ary(1, n)



              'the min and max value now represent the extrema of the points in the array.


              If you have the points in some other format or object, you'll have to come up with a way to loop through it and do the same kind of comparison to find the min and max points.


              2. With the extrema from step 1, use the Pick function to find any route obstructs that either cross or are inside the extrema.  This narrows down the collection of route obstructs to evaluate. You can add them to an arraylist or MGCPCB.Obstructs collection to hold them for later use.  (hint - the arraylist is easier to work with and will do the job just fine)


              3. Now that you have a small number of possible route obstructs to work with, you can afford to be more precise.


              4. Use the IDF polygon to draw an object on a userlayer.


              5. Get the geometry of this object (userlayergfx.geometry). Let's call it idfgeom.


              6 . Get the pointsarray of the idfgeom (idfgeom.pointsarray)


              7. Loop through the collection of obstructs you got earlier.


              8. For each obstruct,

                   - get the geometry and pointsarray.

                   - loop through the points in the obstruct pointsarray

                        - use the geometry.IsPointEnclosed function to see if the point is inside the idfgeom

                   - if no points from the obstruct are inside the idfgeom, do the comparison the other way.  Loop through the idfgeom's pointsarray and see if any of the points are inside the geometry of the objstruct.


              I think that covers the majority of it.  You will need to read the help documentation to see how to use some of these functions; they are all in there. Be sure to read the part about using pointsarrays, and keep in mind that pointsarrays are always declared as datatype Object.


              If you get stuck at some point, don't hesitate to ask more questions.

              • 4. Re: Selecting an object in an area


                Thank you very much

                I don't completely understand paragraph 1&2.

                I'm still learning the subject.

                I'll try understand it better and If i'll have more questions I'll write you.




                • 5. Re: Selecting an object in an area

                  You are most welcome.


                  Where I refer to the "polygon of interest" in those paragraphs, I meant the polygon you are talking about from the IDF data where you said


                  The input I have from the IDF is a collection of points that represent a polygon that I'm looking for in the layout.


                  My point is that you cannot make any assumptions in advance about what that polygon might look like.  It may be a completely odd shape that is nothing like a contiguous rectangle.  In such cases, there may be areas that are included in the rectangle represented by the max and min X and Y values, which are not actually enclosed by the polygon. Kind of like a U-shaped motel with a parking lot in the center area - you can be in the parking lot (inside the extrema) but not actually inside the motel.  So you have to figure out how to handle that kind of situation. If the route obstruct crosses the extrema but is not inside the polygon, do you want to include it in the results or not?  Maybe you do, maybe you don't.  I have no idea of the specifics of what you are trying to accomplish, so you'll have to analyze the objects you are working with, and the goals you have, and decide how to handle the non-simple cases.


                  The general method I outlined will give good results for all cases, regardless of shape.

                  • 6. Re: Selecting an object in an area

                    Thank you very much ,

                    After farther reading and testing it's much clearer.

                    Now I understand that the solution we thought to implement isn't necessary
                    and instead of using a route obstruct as a middle man and convert it to solder
                    mask we can draw the solder mask directly in the layout.

                    The problem I'm facing now, is how to convert the format given in the IDF
                    file to the ArryPoint needed in the PutFabricationgfx in order to draw the
                    solder mask polygon (like you suggested to do in the user layer)?

                    The lines in IDF file have the following format:

                    0          1694.88           2372.04           0

                    0          1694.88           1750                0

                    0          1919.29           1750                0

                    0          1919.29           2324.80           0

                    0          1872.04           2372.04           90.00  

                    0          1694.88           2372.04           0

                    How do I translate the angle (from the IDF) to a radios needs in the arrypoint?

                    I would appreciate any insight in that matter.




                    • 7. Re: Selecting an object in an area

                      The conversion of the IDF points to pointsarray format is mostly straightforward. In the case where the 3rd value is a zero, you simply copy the X and Y values into the points array and make the 3rd element zero also.


                      In the case of the angle value in the 3rd value, you will need to do the math to figure out where the center point of the circle is.  The values given for X and Y in the IDF data represent the endpoint of the arc, so you need to insert another element into the pointsarray, to represent the center of the circle.


                      Pseudo code would look like this:


                      Loop through point data

                           split the line of text into the separate elements, throwing away the first one because it looks like it's always zero

                           if the 3rd element is zero, just copy all three values right into the points array

                           if the 3rd element is not zero then

                                do the math to calclulate the center point of the arc

                                put the coordinates of the center point into the points array, with the 3rd element the value of the radius of the arc

                                add a new element to the pointsarray with the X and Y values from the original data.,  This is the endpoint of the arc.

                           end if


                      End loop

                      The resulting data would look like this:


                      1694.88           2372.04           0

                      1694.88           1750                0

                      1919.29           1750                0

                      1919.29           2324.80           0     'this is the first endpoint of the arc

                      1872.04           2324.80           47.25     'this is the centerpoint of the arc, and the radius

                      1872.04           2372.04           0          'this is the endpoint of the arc

                      1694.88           2372.04           0


                      You see that there are now 7 rows of data, where there were only 6 before.


                      The math involved to find the center of the arc is fairly complicated.  You have to consider that the line before the arc could be coming from any direction, and the angle can be any value from 0 to 360, and positive or negative.  It's a handful to wrap your mind around.  Not undoable, but will take you some time to figure it all out.  When I have done problems like this in the past, I found it helpful to construct a cardboard circle/angle wheel with 2 arrows pinned to the center.  I used the two arrows to visualize the relationship between the three points needed to define the arc.  The tricky case is where the included angle goes across the 0°/360° point, because then you have to reset to the new reference.


                      10° - 27° is not -17°, but 343°


                      Your trig and math skills will get a workout.

                      • 8. Re: Selecting an object in an area

                        Thank you very much !

                        Your answers were very helpful