static void qcad_ruler_instance_finalize (GObject *object)
  {
  int Nix ;
  QCADRuler *ruler = QCAD_RULER (object) ;

  DBG_OO (fprintf (stderr, "QCADRuler::instance_finalize:Entering\n")) ;
  for (Nix = 0 ; Nix < ruler->labels->icUsed ; Nix++)
    g_object_unref (G_OBJECT (exp_array_index_1d (ruler->labels, GRADUATION, Nix).lbl)) ;
  exp_array_free (ruler->labels) ;
  G_OBJECT_CLASS (g_type_class_peek (g_type_parent (QCAD_TYPE_RULER)))->finalize (object) ;
  DBG_OO (fprintf (stderr, "QCADRuler::instance_finalize:Leaving\n")) ;
  }
Beispiel #2
0
// This function always returns NULL
EXP_ARRAY *exp_array_free (EXP_ARRAY *exp_array)
  {
  int Nix ;

  if (NULL == exp_array) return NULL ;

  if (exp_array->icDimensions > 1)
    for (Nix = 0 ; Nix < exp_array->icUsed ; Nix++)
      exp_array_free (((EXP_ARRAY **)(exp_array->data))[Nix]) ;

  if (NULL != exp_array->data)
    g_free (exp_array->data) ;
  g_free (exp_array) ;

  return NULL ;
  }
Beispiel #3
0
// start helpers
static void swap_buses (GtkTreeModel *tm, GtkTreeSelection *sel, bus_layout_D *dialog, GtkTreePath *tpSrc, GtkTreePath *tpDst)
  {
  int Nix ;
  GtkTreeIter itr ;
  SWAP_BUSES_STRUCT src, dst ;
  SWAP_BUSES_STRUCT *min = NULL, *max = NULL ;
  EXP_ARRAY *ar_bSelSrc = NULL, *ar_bSelDst = NULL ;
  gboolean bDstExpanded = TRUE ;

  if (!gtk_tree_model_get_iter (tm, &(src.itr), tpSrc)) return ;
  src.tp = gtk_tree_path_copy (tpSrc) ;
  src.icChildren = gtk_tree_model_iter_n_children (tm, &(src.itr)) ;

  if (!gtk_tree_model_get_iter (tm, &(dst.itr), tpDst))
    {
    gtk_tree_path_free (src.tp) ;
    return ;
    }
  dst.tp = gtk_tree_path_copy (tpDst) ;
  dst.icChildren = gtk_tree_model_iter_n_children (tm, &(dst.itr)) ;

  if (dst.icChildren < src.icChildren)
    {
    min = &dst ;
    max = &src ;
    }
  else
    {
    min = &src ;
    max = &dst ;
    }

  bDstExpanded = gtk_tree_view_row_expanded (gtk_tree_selection_get_tree_view (sel), dst.tp) ;

  g_signal_handlers_block_matched (G_OBJECT (sel), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer)tree_view_selection_changed, NULL) ;

  for (Nix = 0 ; Nix < max->icChildren - min->icChildren ; Nix++)
    gtk_tree_store_append (GTK_TREE_STORE (tm), &itr, &(min->itr)) ;

  gtk_tree_path_down (src.tp) ;
  gtk_tree_path_down (dst.tp) ;

  ar_bSelSrc = exp_array_new (sizeof (gboolean), 1) ;
  ar_bSelDst = exp_array_new (sizeof (gboolean), 1) ;
  exp_array_1d_insert_vals (ar_bSelSrc, NULL, max->icChildren, 0) ;
  exp_array_1d_insert_vals (ar_bSelDst, NULL, max->icChildren, 0) ;

  for (Nix = 0 ; Nix < max->icChildren ; Nix++)
    {
    exp_array_index_1d (ar_bSelSrc, gboolean, Nix) =
      gtk_tree_selection_path_is_selected (sel, src.tp) ;
    exp_array_index_1d (ar_bSelDst, gboolean, Nix) =
      gtk_tree_selection_path_is_selected (sel, dst.tp) ;

    gtk_tree_path_next (src.tp) ;
    gtk_tree_path_next (dst.tp) ;
    }

  if (!gtk_tree_path_up (src.tp)) goto swap_buses_quit ;
  if (!gtk_tree_path_up (dst.tp)) goto swap_buses_quit ;
  gtk_tree_path_down (src.tp) ;
  gtk_tree_path_down (dst.tp) ;

  for (Nix = 0 ; Nix < max->icChildren ; Nix++)
    {
    if (exp_array_index_1d (ar_bSelDst, gboolean, Nix))
      gtk_tree_view_expand_to_path (gtk_tree_selection_get_tree_view (sel), src.tp) ;

    if (exp_array_index_1d (ar_bSelSrc, gboolean, Nix))
      gtk_tree_view_expand_to_path (gtk_tree_selection_get_tree_view (sel), dst.tp) ;

    gtk_tree_path_next (src.tp) ;
    gtk_tree_path_next (dst.tp) ;
    }

  if (!gtk_tree_path_up (src.tp)) goto swap_buses_quit ;
  if (!gtk_tree_path_up (dst.tp)) goto swap_buses_quit ;
  gtk_tree_path_down (src.tp) ;
  gtk_tree_path_down (dst.tp) ;

  for (Nix = 0 ; Nix < max->icChildren ; Nix++)
    {
    swap_model_paths_contents (tm, src.tp, dst.tp) ;
    gtk_tree_path_next (src.tp) ;
    gtk_tree_path_next (dst.tp) ;
    }

  if (!gtk_tree_path_up (src.tp)) goto swap_buses_quit ;
  if (!gtk_tree_path_up (dst.tp)) goto swap_buses_quit ;
  gtk_tree_path_down (src.tp) ;
  gtk_tree_path_down (dst.tp) ;

  for (Nix = 0 ; Nix < max->icChildren ; Nix++)
    {
    GTK_TREE_SELECTION_SET_PATH_SELECTED (sel, src.tp, exp_array_index_1d (ar_bSelDst, gboolean, Nix)) ;
    GTK_TREE_SELECTION_SET_PATH_SELECTED (sel, dst.tp, exp_array_index_1d (ar_bSelSrc, gboolean, Nix)) ;
    gtk_tree_path_next (src.tp) ;
    gtk_tree_path_next (dst.tp) ;
    }

  if (!gtk_tree_path_up (src.tp)) goto swap_buses_quit ;
  if (!gtk_tree_path_up (dst.tp)) goto swap_buses_quit ;

  swap_model_paths_contents (tm, src.tp, dst.tp) ;

  gtk_tree_path_down (src.tp) ;
  gtk_tree_path_down (dst.tp) ;

  for (Nix = 0 ; Nix < min->icChildren ; Nix++)
    gtk_tree_path_next (max->tp) ;
  if (gtk_tree_model_get_iter (tm, &itr, max->tp))
    while (gtk_tree_store_remove (GTK_TREE_STORE (tm), &itr)) ;

  if (!bDstExpanded)
    {
    for (Nix = 0 ; Nix < ar_bSelDst->icUsed ; Nix++)
      if (exp_array_index_1d (ar_bSelDst, gboolean, Nix))
        break ;

    if (Nix == ar_bSelDst->icUsed)
      if (gtk_tree_path_up (src.tp))
        gtk_tree_view_collapse_row (gtk_tree_selection_get_tree_view (sel), src.tp) ;
    }

swap_buses_quit:

  exp_array_free (ar_bSelSrc) ;
  exp_array_free (ar_bSelDst) ;
  gtk_tree_path_free (src.tp) ;
  gtk_tree_path_free (dst.tp) ;
  g_signal_handlers_unblock_matched (G_OBJECT (sel), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, (gpointer)tree_view_selection_changed, NULL) ;
  tree_view_selection_changed (sel, dialog) ;
  }
Beispiel #4
0
static void DialogToBusLayout (bus_layout_D *dialog, BUS_LAYOUT *bus_layout)
  {
  GtkTreeModel *tm = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->tview)) ;
  int Nix ;
  int icTopLevel = gtk_tree_model_iter_n_children (tm, NULL), icCells = -1 ;
  GtkTreePath *tp = NULL, *tpCells = NULL ;
  GtkTreeIter itr ;
  int Nix1, idxCell = -1 ;
  int row_type ;
  EXP_ARRAY *cell_list = NULL ;
  BUS *bus ;

  // destroy all buses before adding the new ones
  for (Nix = bus_layout->buses->icUsed - 1 ; Nix > -1 ; Nix--)
    {
    exp_array_free (exp_array_index_1d (bus_layout->buses, BUS, Nix).cell_indices) ;
    g_free (exp_array_index_1d (bus_layout->buses, BUS, Nix).pszName) ;
    }
  exp_array_remove_vals (bus_layout->buses, 1, 0, bus_layout->buses->icUsed) ;

  // Since we've destroyed all buses, no cells are members of any bus any longer
  for (Nix = 0 ; Nix < bus_layout->inputs->icUsed ; Nix++)
    exp_array_index_1d (bus_layout->inputs, BUS_LAYOUT_CELL, Nix).bIsInBus = FALSE ;
  for (Nix = 0 ; Nix < bus_layout->outputs->icUsed ; Nix++)
    exp_array_index_1d (bus_layout->outputs, BUS_LAYOUT_CELL, Nix).bIsInBus = FALSE ;

  if (icTopLevel > 0)
    {
    tp = gtk_tree_path_new_first () ;
    for (Nix = 0 ; Nix < icTopLevel ; Nix++, gtk_tree_path_next (tp))
      {
      if (gtk_tree_model_get_iter (tm, &itr, tp))
        {
        gtk_tree_model_get (tm, &itr, BUS_LAYOUT_MODEL_COLUMN_TYPE, &row_type, -1) ;
        if (ROW_TYPE_BUS & row_type)
          {
          exp_array_1d_insert_vals (bus_layout->buses, NULL, 1, -1) ;
          bus = &(exp_array_index_1d (bus_layout->buses, BUS, bus_layout->buses->icUsed - 1)) ;
          gtk_tree_model_get (tm, &itr, BUS_LAYOUT_MODEL_COLUMN_NAME, &(bus->pszName), -1) ;
          if (ROW_TYPE_INPUT & row_type)
            {
            bus->bus_function = QCAD_CELL_INPUT ;
            cell_list = bus_layout->inputs ;
            }
          else
            {
            bus->bus_function = QCAD_CELL_OUTPUT ;
            cell_list = bus_layout->outputs ;
            }
          bus->cell_indices = exp_array_new (sizeof (int), 1) ;
          if ((icCells = gtk_tree_model_iter_n_children (tm, &itr)) > 0)
            {
            gtk_tree_path_down (tpCells = gtk_tree_path_copy (tp)) ;

            for (Nix1 = 0 ; Nix1 < icCells ; Nix1++, gtk_tree_path_next (tpCells))
              if (gtk_tree_model_get_iter (tm, &itr, tpCells))
                {
                gtk_tree_model_get (tm, &itr, BUS_LAYOUT_MODEL_COLUMN_INDEX, &idxCell, -1) ;
                exp_array_1d_insert_vals (bus->cell_indices, &idxCell, 1, -1) ;
                // Flag this cell in the master cell list as a member of some bus
                exp_array_index_1d (cell_list, BUS_LAYOUT_CELL, idxCell).bIsInBus = TRUE ;
                }
            gtk_tree_path_free (tpCells) ;
            }
          }
        }
      }
    gtk_tree_path_free (tp) ;
    }
  }
static void precompute (QCADElectrode *electrode)
  {
  int Nix, Nix1 ;
  WorldPoint ptSrcLine, ptDstLine ;
  double factor1, factor2, dstx_minus_srcx, dsty_minus_srcy ;
  double pt1x_minus_pt0x, pt1y_minus_pt0y, pt3x_minus_pt2x, pt3y_minus_pt2y ;
  double reciprocal_of_x_divisions, reciprocal_of_y_divisions ;
  QCADRectangleElectrode *rc_electrode = QCAD_RECTANGLE_ELECTRODE (electrode) ;
  QCADDesignObject *obj = QCAD_DESIGN_OBJECT (electrode) ;
  double 
    kose =  cos (rc_electrode->angle),
    msin = -sin (rc_electrode->angle),
    sine =  sin (rc_electrode->angle),
    half_cx = rc_electrode->cxWorld / 2.0,
    half_cy = rc_electrode->cyWorld / 2.0,
    xMin, yMin, xMax, yMax ;
  WorldPoint pt[4] = {{0,0},{0,0},{0,0},{0,0}}, ptCenter = {0,0} ;

  // Call parent precompute function
  QCAD_ELECTRODE_CLASS (g_type_class_peek (g_type_parent (QCAD_TYPE_RECTANGLE_ELECTRODE)))->precompute (electrode) ;

  ptCenter.xWorld = obj->bounding_box.xWorld + obj->bounding_box.cxWorld / 2.0 ;
  ptCenter.yWorld = obj->bounding_box.yWorld + obj->bounding_box.cyWorld / 2.0 ;

  // Create corner points
  pt[0].xWorld = ptCenter.xWorld - half_cx ;
  pt[0].yWorld = ptCenter.yWorld - half_cy ;
  pt[1].xWorld = ptCenter.xWorld + half_cx ;
  pt[1].yWorld = ptCenter.yWorld - half_cy ;
  pt[2].xWorld = ptCenter.xWorld + half_cx ;
  pt[2].yWorld = ptCenter.yWorld + half_cy ;
  pt[3].xWorld = ptCenter.xWorld - half_cx ;
  pt[3].yWorld = ptCenter.yWorld + half_cy ;

  if (0 != rc_electrode->angle)
    {
    // rotate corner points
    rc_electrode->precompute_params.pt[0].xWorld = kose * pt[0].xWorld + sine * pt[0].yWorld ;
    rc_electrode->precompute_params.pt[0].yWorld = msin * pt[0].xWorld + kose * pt[0].yWorld ;
    rc_electrode->precompute_params.pt[1].xWorld = kose * pt[1].xWorld + sine * pt[1].yWorld ;
    rc_electrode->precompute_params.pt[1].yWorld = msin * pt[1].xWorld + kose * pt[1].yWorld ;
    rc_electrode->precompute_params.pt[2].xWorld = kose * pt[2].xWorld + sine * pt[2].yWorld ;
    rc_electrode->precompute_params.pt[2].yWorld = msin * pt[2].xWorld + kose * pt[2].yWorld ;
    rc_electrode->precompute_params.pt[3].xWorld = kose * pt[3].xWorld + sine * pt[3].yWorld ;
    rc_electrode->precompute_params.pt[3].yWorld = msin * pt[3].xWorld + kose * pt[3].yWorld ;

    // Find binding box
    xMin = MIN (rc_electrode->precompute_params.pt[0].xWorld, MIN (rc_electrode->precompute_params.pt[1].xWorld, MIN (rc_electrode->precompute_params.pt[2].xWorld, rc_electrode->precompute_params.pt[3].xWorld))) ;
    xMax = MAX (rc_electrode->precompute_params.pt[0].xWorld, MAX (rc_electrode->precompute_params.pt[1].xWorld, MAX (rc_electrode->precompute_params.pt[2].xWorld, rc_electrode->precompute_params.pt[3].xWorld))) ;
    yMin = MIN (rc_electrode->precompute_params.pt[0].yWorld, MIN (rc_electrode->precompute_params.pt[1].yWorld, MIN (rc_electrode->precompute_params.pt[2].yWorld, rc_electrode->precompute_params.pt[3].yWorld))) ;
    yMax = MAX (rc_electrode->precompute_params.pt[0].yWorld, MAX (rc_electrode->precompute_params.pt[1].yWorld, MAX (rc_electrode->precompute_params.pt[2].yWorld, rc_electrode->precompute_params.pt[3].yWorld))) ;

    obj->bounding_box.xWorld = xMin ;
    obj->bounding_box.yWorld = yMin ;
    obj->bounding_box.cxWorld = xMax - xMin ;
    obj->bounding_box.cyWorld = yMax - yMin ;
    obj->x = obj->bounding_box.xWorld + obj->bounding_box.cxWorld / 2.0 ;
    obj->y = obj->bounding_box.yWorld + obj->bounding_box.cyWorld / 2.0 ;

    // move points back
    rc_electrode->precompute_params.pt[0].xWorld += ptCenter.xWorld - obj->x ;
    rc_electrode->precompute_params.pt[0].yWorld += ptCenter.yWorld - obj->y ;
    rc_electrode->precompute_params.pt[1].xWorld += ptCenter.xWorld - obj->x ;
    rc_electrode->precompute_params.pt[1].yWorld += ptCenter.yWorld - obj->y ;
    rc_electrode->precompute_params.pt[2].xWorld += ptCenter.xWorld - obj->x ;
    rc_electrode->precompute_params.pt[2].yWorld += ptCenter.yWorld - obj->y ;
    rc_electrode->precompute_params.pt[3].xWorld += ptCenter.xWorld - obj->x ;
    rc_electrode->precompute_params.pt[3].yWorld += ptCenter.yWorld - obj->y ;
    obj->bounding_box.xWorld += ptCenter.xWorld - obj->x ;
    obj->bounding_box.yWorld += ptCenter.yWorld - obj->y ;
    obj->x = ptCenter.xWorld ;
    obj->y = ptCenter.yWorld ;
    }
  else
    {
    rc_electrode->precompute_params.pt[0] = pt[0] ;
    rc_electrode->precompute_params.pt[1] = pt[1] ;
    rc_electrode->precompute_params.pt[2] = pt[2] ;
    rc_electrode->precompute_params.pt[3] = pt[3] ;
    obj->bounding_box.xWorld = pt[0].xWorld ;
    obj->bounding_box.yWorld = pt[0].yWorld ;
    obj->bounding_box.cxWorld = rc_electrode->cxWorld ;
    obj->bounding_box.cyWorld = rc_electrode->cyWorld ;
    obj->x = obj->bounding_box.xWorld + obj->bounding_box.cxWorld / 2.0 ;
    obj->y = obj->bounding_box.yWorld + obj->bounding_box.cyWorld / 2.0 ;
    }

  if (NULL != rc_electrode->precompute_params.pts)
    exp_array_free (rc_electrode->precompute_params.pts) ;

  rc_electrode->precompute_params.pts = exp_array_new (sizeof (WorldPoint), 2) ;

  for (Nix = 0 ; Nix < rc_electrode->n_y_divisions ; Nix++)
    exp_array_insert_vals (rc_electrode->precompute_params.pts, NULL, rc_electrode->n_x_divisions, 2, -1, TRUE, 0, TRUE) ;

  // This is a faaar better place to multiply by 1e9 than get_potential
  rc_electrode->precompute_params.rho_factor = 1e9 * QCAD_ELECTRODE (rc_electrode)->precompute_params.capacitance / (rc_electrode->n_x_divisions * rc_electrode->n_y_divisions) ;
  pt1x_minus_pt0x = rc_electrode->precompute_params.pt[1].xWorld - rc_electrode->precompute_params.pt[0].xWorld ;
  pt1y_minus_pt0y = rc_electrode->precompute_params.pt[1].yWorld - rc_electrode->precompute_params.pt[0].yWorld ;
  pt3x_minus_pt2x = rc_electrode->precompute_params.pt[3].xWorld - rc_electrode->precompute_params.pt[2].xWorld ;
  pt3y_minus_pt2y = rc_electrode->precompute_params.pt[3].yWorld - rc_electrode->precompute_params.pt[2].yWorld ;
  reciprocal_of_x_divisions = 1.0 / rc_electrode->n_x_divisions ;
  reciprocal_of_y_divisions = 1.0 / rc_electrode->n_y_divisions ;
  
  for (Nix = 0 ; Nix < rc_electrode->n_x_divisions ; Nix++)
    {
    factor1 = reciprocal_of_x_divisions * (Nix + 0.5) ;
    factor2 = reciprocal_of_x_divisions * ((rc_electrode->n_x_divisions - Nix) - 0.5) ;

    ptSrcLine.xWorld = rc_electrode->precompute_params.pt[0].xWorld + pt1x_minus_pt0x * factor1 ;
    ptSrcLine.yWorld = rc_electrode->precompute_params.pt[0].yWorld + pt1y_minus_pt0y * factor1 ;
    ptDstLine.xWorld = rc_electrode->precompute_params.pt[2].xWorld + pt3x_minus_pt2x * factor2 ;
    ptDstLine.yWorld = rc_electrode->precompute_params.pt[2].yWorld + pt3y_minus_pt2y * factor2 ;

    dstx_minus_srcx = ptDstLine.xWorld - ptSrcLine.xWorld ;
    dsty_minus_srcy = ptDstLine.yWorld - ptSrcLine.yWorld ;
    for (Nix1 = 0 ; Nix1 < rc_electrode->n_y_divisions ; Nix1++)
      {
      exp_array_index_2d (rc_electrode->precompute_params.pts, WorldPoint, Nix1, Nix).xWorld = 
        ptSrcLine.xWorld + dstx_minus_srcx * reciprocal_of_y_divisions * (Nix1 + 0.5) ;
      exp_array_index_2d (rc_electrode->precompute_params.pts, WorldPoint, Nix1, Nix).yWorld = 
        ptSrcLine.yWorld + dsty_minus_srcy * reciprocal_of_y_divisions * (Nix1 + 0.5) ;
      }
    }
  }