• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC Design
  3. drawing/logo in a schematic view

Stats

  • Locked Locked
  • Replies 9
  • Subscribers 127
  • Views 8567
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

drawing/logo in a schematic view

Aldo2
Aldo2 over 13 years ago

Hello,

is there a way to import/generate a drawing/logo in a schematic view?

Thank you

Aldo 

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 13 years ago

    Aldo,

    This code was originally written for layout logos, but can also be done to create a logo on a symbol which you could then place in your schematic. Note that it needs you to have an xpm (X pixmap) file (which as the advantage of being ASCII) without too many colours. Tools such as gimp can output this, and you can also use utilities in such tools to reduce the number of colours.

    Regards,

    Andrew.

    /* abXpmToLayout.ils
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Jun 15, 2001 
    Modified   A.D.Beckett
    By         Jun 03, 2011 
    
    NOTE: This is SKILL++ code, so please preserve the .ils suffix.
    
    Code to read an X pixmap and draw a layout.
    
    The main entry function is abXpmToLayout(), which should
    be invoked with a layout window being the current window.
    
    Limitations/Ideas for future:
    
    1. This only handles up to something like 62 layers
       properly. This is because the pixmap format changes to use
       more than one character per pixel, and the code rather
       dumbly assumes that there will only ever be one. To
       be fair, setting up all the layer purpose pairs would
       be a nightmare.
    2. Could merge colours which appear similar, to avoid
       having to specify similar colours lots of times.
    3. Some convenience toggles could be added, to turn on or
       off all layers.
    
    Primarily this expected to be used for a small number of
    colours in the pixmap file. This can be arranged using
    other tools (xv, gimp, PC tools etc).
    These tools can also be used to convert from other formats
    to xpm.
    
    Updates:
    
    3rd June 2011: Removed dependency on abSelectFile - uses ddsFileBrowseCB
                   instead.
    
    ***************************************************
    
    SCCS Info: @(#) abXpmToLayout.ils 06/03/11.11:26:31 1.5
    
    */
    
    (importSkillVar abPixMapOptionsForm)
    
    ;------------------------------------------------------------------------
    ; Define classes used within the code
    ;------------------------------------------------------------------------
    
    (defclass abPixMap ()
      (
       (width @initarg width @reader abPixMapGetWidth)
       (height @initarg height @reader abPixMapGetHeight)
       (colours @initarg colours @reader abPixMapGetColours)
       (pixels @initarg pixels @reader abPixMapGetPixels)
       )
      )
    
    (defclass abPixMapColour ()
      (
       (char @initarg char)
       (red @initarg red @reader abPixMapColourGetRed)
       (green @initarg green @reader abPixMapColourGetGreen)
       (blue @initarg blue @reader abPixMapColourGetBlue)
       (lpp @reader abPixMapColourGetLpp @writer abPixMapColourSetLpp)
       )
      )
    
    /***************************************************************
    *                                                              *
    *                (abPixMapColourGetLpp _colour)                *
    *                                                              *
    *   A dummy method, so that if the colour isn't found for a    *
    *        character in the pixel strings, it returns nil        *
    *                                                              *
    ***************************************************************/
    
    (defmethod abPixMapColourGetLpp ((_colour list))
      nil
      )
    
    /***************************************************************
    *                                                              *
    *                 (abPixMapReadFile fileName)                  *
    *                                                              *
    *  Read a pixmap file, and return an instance of the abPixMap  *
    *                          structure.                          *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapReadFile (fileName)
      (let (prt staticFound line data dimensions width height ncolours
    	    colourTable colourInfo red green blue pixmap)
           (unless (setq prt (infile fileName))
    	       (error "Could not read pixmap file %s" fileName)
    	       )
           (rexCompile "static char")
           (while (and (null staticFound) (gets line prt))
    	      (setq staticFound (rexExecute line))
    	      )
           (when staticFound
    	     (setq data t)
    	     (while (equal (setq data (lineread prt)) t) t)
    	     ;-----------------------------------------------------------
    	     ; Swallow any warnings about closing } etc
    	     ;-----------------------------------------------------------
    	     (getWarn)
    	     )
           (close prt)
           (when (and data (nequal data t))
    	     ;-----------------------------------------------------------
    	     ; first entry in the list will be the dimensional information
    	     ;-----------------------------------------------------------
    	     (setq dimensions (linereadstring (car data)))
    	     (setq width (car dimensions))
    	     (setq height (cadr dimensions))
    	     (setq ncolours (caddr dimensions))
    	     (setq data (cdr data))
    	     ;-----------------------------------------------------------
    	     ; Now read the colours
    	     ;-----------------------------------------------------------
    	     (setq colourTable (makeTable 'colourTable nil))
    	     (for colour 1 ncolours
    		  (setq colourInfo (parseString (car data)))
    		  (setq data (cdr data))
    		  (when (cddr colourInfo)
    			(sscanf (caddr colourInfo)
    				"#%2x%2x%2x" red green blue
    				)
    			(setarray colourTable
    				  (car colourInfo)
    				  (makeInstance 'abPixMapColour
    						?char (car colourInfo)
    						?red red || 0
    						?green green || 0
    						?blue blue || 0
    						)
    				  )
    			)
    		  )
    	     ;-----------------------------------------------------------
    	     ; Now create the pixmap object
    	     ;-----------------------------------------------------------
    	     (setq pixmap
    		   (makeInstance 'abPixMap
    		    ?width width
    		    ?height height
    		    ?colours colourTable
    		    ?pixels data
    		    )
    		   )
    	     ) ; when
           pixmap
           )
      )
    
    /***************************************************************
    *                                                              *
    *        abPixMapDrawLayout(@key pixmap (pixelSize 0.1)        *
    *                (cellView (geGetEditCellView))                *
    *                        (origin 0:0))                         *
    *                                                              *
    *      Draw the layout itself from the pixmap structure.       *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapDrawLayout (@key pixmap (pixelSize 0.1) 
    				(cellView (geGetEditCellView))
    				(origin 0:0))
      (let (x y colours rectList lpp)
           (setq colours (abPixMapGetColours pixmap))
           (setq y (yCoord origin))
           ;-----------------------------------------------------------------
           ; Iterate over each row
           ;-----------------------------------------------------------------
           (foreach row (abPixMapGetPixels pixmap)
    		(setq x (xCoord origin))
    		(foreach pixel (parseString row "")
    			 ;-----------------------------------------------
    			 ; Determine the layer purpose pair
    			 ;-----------------------------------------------
    			 (setq lpp 
    			       (abPixMapColourGetLpp (arrayref colours pixel)))
    			 ;-----------------------------------------------
    			 ; Draw the rectangle
    			 ;-----------------------------------------------
    			 (when (and (listp lpp) lpp)
    			       (setq rectList
    				     (cons
    				      (dbCreateRect
    				       cellView
    				       lpp
    				       (list
    					(list x y)
    					(list 
    					 (plus x pixelSize) 
    					 (difference y pixelSize)
    					 )
    					)
    				       )
    				      rectList
    				      )))
    			 (setq x (plus x pixelSize))
    			 )
    		(setq y (difference y pixelSize))
    		)
           ;-----------------------------------------------------------------
           ; Merge all the shapes to reduce the shape count
           ;-----------------------------------------------------------------
           (leMergeShapes rectList)
           t
           ))
    				       
    
    /***************************************************************
    *                                                              *
    *                     (abPixMapCreateForm)                     *
    *                                                              *
    *        Create the options form for the pixmap drawer.        *
    *    Note that all the layers aren't put on the form until     *
    *                    the file has been read                    *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapCreateForm ()
      (let (fileName selectFile pixelSize scrollRegion readFile)
           (setq fileName
    	     (hiCreateStringField
    	      ?name 'fileName
    	      ?prompt "Pixmap File"
    	      )
    	     )
           (setq selectFile
    	     (hiCreateButton
    	      ?name 'selectFile
    	      ?buttonText "Select File"
    	      ?callback "(ddsFileBrowseCB (hiGetCurrentForm) 'fileName)"
    	      )
    	     )
           (setq readFile
    	     (hiCreateButton
    	      ?name 'readFile
    	      ?buttonText "Read File"
    	      ?callback "(abPixMapReadFileCB)"
    	      )
    	     )
           (setq pixelSize
    	     (hiCreateFloatField
    	      ?name 'pixelSize
    	      ?defValue 0.1
    	      ?prompt "Pixel Size"
    	      )
    	     )
           (setq scrollRegion
    	     (hiCreateScrollRegion
    	      ?borderWidth 0
    	      ?name 'layers
    	      )
    	     )
           (hiCreateAppForm
    	?name 'abPixMapOptionsForm
    	?formTitle "Choose pixmap settings"
    	?formType 'options
    	?buttonLayout 'HideCancel
    	?fields (list
    		 (list fileName 0:0 405:35 105)
    		 (list selectFile 105:35 95:30)
    		 (list readFile 205:35 95:30)
    		 (list pixelSize 0:70 405:35 105)
    		 (list
    		  (hiCreateLabel
    		   ?name 'colourLab
    		   ?labelText "Colour"
    		   )
    		  105:105 35:30)
    		 (list
    		  (hiCreateLabel
    		   ?name 'convertLab
    		   ?labelText "Draw"
    		   )
    		  160:105 32:30)
    		 (list
    		  (hiCreateLabel
    		   ?name 'lppLab
    		   ?labelText "Layer"
    		   )
    		  205:105 32:30)
    		 (list scrollRegion 105:130 300:200)
    		 )
    	)
           )
      )
    
    /***************************************************************
    *                                                              *
    *          (abPixMapAddPointCB _windowId _pointList)           *
    *                                                              *
    *     Ignore any points entered before the pixmap has been     *
    *                            read.                             *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapAddPointCB (_windowId _pointList)
      (unless (getq abPixMapOptionsForm pixmap)
    	  (deletePoint)
    	  )
      )
    
    /***************************************************************
    *                                                              *
    *             (abPixMapDoneCB _windowId ok points)             *
    *                                                              *
    *  When the points have been entered, and all is OK, proceed   *
    * to fill the colour structure with the selected layer purpose *
    *  pairs, and then draw the pixmap starting at the specified   *
    *                         coordinates.                         *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapDoneCB (_windowId ok points)
      (let (pixmap)
           (setq pixmap (getq abPixMapOptionsForm pixmap))
           (when (and ok points pixmap)
    	     (abPixMapFillInLpps (getq abPixMapOptionsForm layers) pixmap)
    	     (abPixMapDrawLayout
    	      ?pixmap pixmap
    	      ?pixelSize (getq (getq abPixMapOptionsForm pixelSize) value)
    	      ?cellView (getq abPixMapOptionsForm cellView)
    	      ?origin (car points)
    	      )
    	     )
           )
      )
    
    /***************************************************************
    *                                                              *
    *                (abPixMapGetLayer layerString)                *
    *                                                              *
    *      Because we have multiple layer cyclic fields, need      *
    *       to extract the layer purpose pair name ourselves       *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapGetLayer (layerString)
      (let (layer)
           (setq layer (linereadstring layerString))
           (list (get_string (car layer))
                 (get_string (caadr layer)))))
    
    
    /***************************************************************
    *                                                              *
    *              (abPixMapFillInLpps region pixmap)              *
    *                                                              *
    *     Given the scroll region on the form, and the pixmap      *
    *     instance, fill in the lpp information in the colour      *
    *     structures, based on what was selected on the form.      *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapFillInLpps (region pixmap)
      (let (colours colourNum colour)
           (setq colours (abPixMapGetColours pixmap))
           (setq colourNum 0)
           ;-----------------------------------------------------------------
           ; Loop through all the colour names
           ;-----------------------------------------------------------------
           (foreach colourName (getq region colourNames)
    		(setq colour (arrayref colours colourName))
    		(abPixMapColourSetLpp
    		 colour
    		 (and (getq (get region (concat 'convert colourNum)) value)
    		      (abPixMapGetLayer 
    		       (cadddr
    			(getq (get region (concat 'lpp colourNum)) value))
    		       )
    		      )
    		 )
    		(postincrement colourNum)
    		)
           )
      )
    
    
    /****************************************************************
    *                                                               *
    *                     (abPixMapReadFileCB)                      *
    *                                                               *
    * Callback for the read file button. When this is done, it must *
    * read the pixmap structure, and fill in the scroll region with *
    *                    the appropriate layers.                    *
    *                                                               *
    ****************************************************************/
    
    (defun abPixMapReadFileCB ()
      (let (fileName pixmap)
           (setq fileName (getq (getq abPixMapOptionsForm fileName) value))
           (unless (blankstrp fileName)
    	       ;---------------------------------------------------------
    	       ; Read the pixmap
    	       ;---------------------------------------------------------
    	       (setq pixmap (abPixMapReadFile fileName))
    	       (when pixmap
    		     ;---------------------------------------------------
    		     ; Put the layers into the scroll region
    		     ;---------------------------------------------------
    		     (abPixMapFillScrollRegion 
    		      pixmap (getq abPixMapOptionsForm layers) 
    		      (getq abPixMapOptionsForm cellView))
    		     ;---------------------------------------------------
    		     ; Record the pixmap for posterity
    		     ;---------------------------------------------------
    		     (putpropq abPixMapOptionsForm pixmap pixmap)
    		     ;---------------------------------------------------
    		     ; Change the enter function - primarily to change
    		     ; the prompt
    		     ;---------------------------------------------------
    		     (changeEnterFun 'enterPoint
    				     ?prompts 
    				     '("Point at top left origin of pixmap")
    				     ?form abPixMapOptionsForm
    				     ?addPointProc "abPixMapAddPointCB"
    				     ?doneProc "abPixMapDoneCB"
    				     ?noInfix t
    				     ?alwaysMap t
    				     )
    		     )
    	       )
           )
      )
    
    /***************************************************************
    *                                                              *
    *              (abPixMapCreateColourIcon colour)               *
    *                                                              *
    *  Build a small coloured icon in the colour which was in the  *
    *    original pixmap (or as close to it as we can get given    *
    *               the colour limitations in DFII)                *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapCreateColourIcon (colour)
      (let (colourArray
    	(line "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
    	)
           (setq colourArray (hiCreateColorArray))
           (setarray colourArray 0
    		 (hiMatchColor
    		  (foreach mapcar intensity
    			   (list
    			    (abPixMapColourGetRed colour)
    			    (abPixMapColourGetGreen colour)
    			    (abPixMapColourGetBlue colour)
    			    )
    			   (round (times intensity 3.915))
    			   )
    		  ) 
    		 )
           (hiStringToIcon
    	colourArray
    	strcat(line line line line line line)
    	32 6
    	)
           )
      )
    
    /***************************************************************
    *                                                              *
    *      (abPixMapFillScrollRegion pixmap region cellView)       *
    *                                                              *
    *   Fill the scroll region with all the colours found in the   *
    *                         pixmap file                          *
    *                                                              *
    ***************************************************************/
    
    (defun abPixMapFillScrollRegion (pixmap region cellView)
      (let (current colours colourNames colourNum button y lpp tfId convert
    		icon)
           (setq tfId (techGetTechFile cellView))
           ;-----------------------------------------------------------------
           ; Erase any current layer definitions
           ;-----------------------------------------------------------------
           (setq current (getq region fieldList))
           (when current (hiDeleteFields region current))
           ;-----------------------------------------------------------------
           ; Add the labels at the top
           ;-----------------------------------------------------------------
           (setq colours (abPixMapGetColours pixmap))
           (setq colourNames (sort (getq colours ?) 'alphalessp))
           (setq colourNum 0)
           ;-----------------------------------------------------------------
           ; Remember the colour names to ease lookup later
           ;-----------------------------------------------------------------
           (putpropq region colourNames colourNames)
           ;-----------------------------------------------------------------
           ; Build the scrollable region on the form
           ;-----------------------------------------------------------------
           (foreach colourName colourNames
    		(setq icon
    		      (abPixMapCreateColourIcon (arrayref colours colourName)))
    		;--------------------------------------------------------
    		; The pretty coloured button, corresponding
    		; to the colour in the original pixmap
    		;--------------------------------------------------------
    		(setq button
    		      (hiCreateButton
    		       ?name (concat 'colour colourNum)
    		       ?buttonIcon icon
    		       )
    		      )
    		;--------------------------------------------------------
    		; Boolean button to enable the layer
    		;--------------------------------------------------------
    		(setq convert
    		      (hiCreateBooleanButton
    		       ?name (concat 'convert colourNum)
    		       ?buttonText " "
    		       ?defValue t
    		       ?value t
    		       )
    		      )
    		;--------------------------------------------------------
    		; Create the layer cyclic box
    		;--------------------------------------------------------
    		(setq lpp
    		      (hiCreateLayerCyclicField
    		       tfId
    		       "Choose"
    		       ""
    		       (leGetValidLayerList tfId)
    		       ))
    		;--------------------------------------------------------
    		; Make sure field symbol is unique
    		;--------------------------------------------------------
    		(putpropq lpp
    			  (concat 'lpp colourNum) hiFieldSym)
    
    		(setq y (times colourNum 35))
    		(hiAddFields region
    			     (list
    			      (list button 0:y+11 32:12)
    			      (list convert 60:y 20:35 0)
    			      (list lpp 100:y 150:35 0)
    			      )
    			    )
    		(postincrement colourNum)
    		)
           )
      )
    
    /***************************************************************
    *                                                              *
    *                       (abXpmToLayout)                        *
    *                                                              *
    *           Main entry point for the pixmap drawer.            *
    *                                                              *
    ***************************************************************/
    
    (defun abXpmToLayout ()
      (let (current)
           (unless (boundp 'abPixMapOptionsForm)
    	       (abPixMapCreateForm))
           (setq current (getq (getq abPixMapOptionsForm layers) fieldList))
           (when current (hiDeleteFields (getq abPixMapOptionsForm layers) current))
           (putpropq abPixMapOptionsForm (geGetEditCellView) cellView)
           (putpropq abPixMapOptionsForm nil pixmap)
           (enterPoint
    	?prompts '("Use options form to specify file to read")
    	?form abPixMapOptionsForm
    	?addPointProc "abPixMapAddPointCB"
    	?doneProc "abPixMapDoneCB"
    	?noInfix t
    	?alwaysMap t
    	)
           )
      ) 
    

     

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Aldo2
    Aldo2 over 13 years ago
    Thank you very much Andrew Best regards Aldo
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • thorstenb
    thorstenb over 8 years ago

    Hello Andy:

    many thanks for this .ils script !

    I can import an xpm file with good success, but I am facing one issue:

    For some reason, the aspect ratio is not preserved during import,
    ie I am getting a layout structure made from imported shapes that is scaled by a factor of 2 along the x-axis.

    Looking at the code, I have to admit I do not understand where this might come from.

    The scaling error is independent of the actual pixel size entered.

    Using virtuoso IC6.1.7-64b.500.11 in L or XL modes.

    Any help on this scaling issue is greatly appreciated. Thanks !

    Best Regards,

    Thorsten

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Thorsten,

    I can't see any way that can happen with the code. Can you send me the xpm file? If you don't want to post it in the forums, please send me a friend request and then I'll accept that and we can share the file that way (note, this is not an invitation to all users to send me friend requests; I don't normally accept them in order to limit the number of direct questions I get so that they are manageable!).

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • thorstenb
    thorstenb over 8 years ago
    Hello Andrew !

    This is great, thank you very much for following up that quickly to a relatively old thread.
    Yes, I will send the xpm via private comms to solve the issue.

    Best Regards,
    Thorsten
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    For the benefit of anyone else who hits a similar issue, here's what I found after Thorsten sent me the xpm file:

    The reason is that your image has too many colours in it. At the top of the code, it says (in the limitations section):

    1. This only handles up to something like 62 layers
       properly. This is because the pixmap format changes to use
       more than one character per pixel, and the code rather
       dumbly assumes that there will only ever be one. To
       be fair, setting up all the layer purpose pairs would
       be a nightmare.

    Your image has 256 colours. Because of this each pixel is represented by two characters, whereas my code dumbly assumes one character per pixel. So that means that each pixel is something like "UX" and it then draws two pixels for each actual pixel. Hence the problem.

    What I did was to use gimp on the xpm file and then use Image->Mode->Indexed and set the maximum number of colours to 2 (under Generate Optimised palette - probably could have used the black and white mode too because you only really seemed to have 2 colours in the image), and saved the xpm file again (attached).

    This then works fine.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • drdanmc
    drdanmc over 8 years ago
    Thanks for the code here Andrew. I was looking for the same thing. I ran into a couple of issues that were not too hard to solve but thought I'd share them in case others hit them.

    Here is the top of my XPM file:

    /* XPM */
    static char *tmp[] = {
    /* columns rows colors chars-per-pixel */
    "538 126 2 1 ",
    " c #050708",
    ". c None",
    /* pixels */
    "... ......

    In this case, it is a space character used for the first color. The code which parses that color definition doesn't seem to deal well with the space. The other thing I ran into is the particular XPM file I had came from a PNG which was black on transparent. I used ImageMagick's convert utility to create the xpm with "convert mylogo.png mylogo.xpm" and ended up with the "None" for the color associated with".". As a quick workaround I just edited the XPM file to avoid those two issues.

    What I'm now left with is two challenges.

    1) I'm trying to figure out if there is a lpp which is likely to always be filled. Since this is for a logo which will go in a title block symbol, I will want it to work fairly well without regards to the PDK currently in use.

    2) I'm having troubles trading off sufficient resolution to make the logo look good with getting it the right size to fit in the title block. Back in CDDB days, there was a 'mag' property I could put on a symbol to size it to whatever was needed. It seems OA doesn't have that. When I pick a pixel size small enough my resolution is a bit lacking. Any suggestions? I've actually been thinking about trying to see if I can use potrace (maybe from within inkscape) and generate points on a polygon instead of using square pixels to approximate a curve.

    -Dan
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Dan,

    Thanks for the feedback. Unfortunately I didn't spend a lot of time trying to make the parser really robust (in other words I used empirical examples rather than trying to find the XPM specification and ensure that I was fully compliant). The dangers of pragmatism over completeness!

    In terms of answering your questions:

    1. You could probably use device/drawing1 - this is normally solid green. Also pin drawing (solid red).
    2. You could use dbCreateXformPCell() which will create you a pcell with a mag parameter to emulate the old CDB mag. Of course, you'll still have a pixellated image - but may be more convenient? For another customer a few years ago I ended up hand converting their SVG logo into a pcell, using a bunch of utility functions to create cubic bezier curves. That allowed me to have a scalable vector logo pcell. I'll post the cubic bezier code below - not sure this really helps you here though!
    /* abCubicBezier.il
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Nov 29, 2006 
    Modified   
    By         
    
    Code to generate cubic bezier curves
    
    Examples:
    
    abPlotBezier(600:500 900:500 600:350 900:650 "y0")
    abPlotBezier(600:200 900:200 675:100 975:100 "y0")
    abPlotBezier(100:200 400:200 100:100 400:100 "y0")
    abPlotBezier(100:500 400:500 25:400 475:400 "y0")
    
    ***************************************************
    
    SCCS Info: @(#) abCubicBezier.il 11/29/06.17:23:32 1.1
    
    */
    
    /****************************************************************
    *                                                               *
    *                 abPointOnCubicBezier (cp tp)                  *
    *                                                               *
    *                cp is a 4 element array where:                 *
    *    cp[0] is the starting point, or P0 in the above diagram    *
    * cp[1] is the first control point, or P1 in the above diagram  *
    * cp[2] is the second control point, or P2 in the above diagram *
    *      cp[3] is the end point, or P3 in the above diagram       *
    *            tp is the parameter value, 0 <= tp <= 1            *
    *                                                               *
    ****************************************************************/
    
    defun(abPointOnCubicBezier (cp tp)
    let((ax bx cx ay by cy tSquared tCubed)
    
        ;--------------------------------------------------------------------
        ; calculate the polynomial coefficients
        ;--------------------------------------------------------------------
        cx = 3.0 * (xCoord(cp[1]) - xCoord(cp[0]))
        bx = 3.0 * (xCoord(cp[2]) - xCoord(cp[1])) - cx
        ax = xCoord(cp[3]) - xCoord(cp[0]) - cx - bx
            
        cy = 3.0 * (yCoord(cp[1]) - yCoord(cp[0]))
        by = 3.0 * (yCoord(cp[2]) - yCoord(cp[1])) - cy
        ay = yCoord(cp[3]) - yCoord(cp[0]) - cy - by
            
        ;--------------------------------------------------------------------
        ; calculate the curve point at parameter value tp
        ;--------------------------------------------------------------------
        tSquared = tp * tp
        tCubed = tSquared * tp
            
        ;--------------------------------------------------------------------
        ; The result
        ;--------------------------------------------------------------------
        (ax * tCubed) + (bx * tSquared) + (cx * tp) + xCoord(cp[0]):
        (ay * tCubed) + (by * tSquared) + (cy * tp) + yCoord(cp[0])
    
        ) 
    ) ; defun
    
    /***************************************************************
    *                                                              *
    *             abComputeBezier (cp numberOfPoints)              *
    *                                                              *
    *                   returns a list of points                   *
    *            generated from the control points cp.             *
    *                                                              *
    ***************************************************************/
    
    defun(abComputeBezier (cp numberOfPoints) 
    let((dt result)
    
        dt = 1.0 / ( numberOfPoints - 1 )
    
        for(i 0 sub1(numberOfPoints)
            result=tconc(result abPointOnCubicBezier(cp i*dt))
        ) ; for
        car(result)
    ))
    
    /***************************************************************
    *                                                              *
    *          abPlotBezier (from to p1 p2 layerName @key          *
    *       (numPoints 200) (cellView (geGetEditCellView)))        *
    *                                                              *
    *     Example function to plot a line from the calculated      *
    *                           points.                            *
    *                                                              *
    ***************************************************************/
    
    defun(abPlotBezier (from to p1 p2 layerName @key 
        (numPoints 200) (cellView (geGetEditCellView)))
    let((cp pointList)
    
        declare(cp[4])
    
        ;--------------------------------------------------------------------
        ; Put coefficients in an array
        ;--------------------------------------------------------------------
        cp[0]=from
        cp[3]=to
        cp[1]=p1
        cp[2]=p2
    
        pointList=abComputeBezier(cp numPoints)
        dbCreateLine(cellView layerName pointList)
    ))
    
    

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • drdanmc
    drdanmc over 8 years ago
    cool! This may be the way for me to go. Much appreciated.

    Thanks
    -Dan
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information