Drawing Cleanup Details

AutoCAD Map 3D ObjectARX

 
Drawing Cleanup Details
 
 
 

Let's look at this in two phases, preparing the cleanup model, which ends with a call to tpm_cleaninit, and executing the cleanup, which begins with a call to tpm_cleanstart.

To prepare the cleanup model

  1. Allocate memory for the cleanup model. Use tpm_cleanalloc.
    ade_id cleanupModelId = tpm_cleanalloc();
  2. Allocate memory for cleanup variables, which specify properties for the cleanup process. The variables are initialized to their default values. Use tpm_varalloc.
    ade_id cleanupVarId = tpm_varalloc();

    If you will be specifying an explicit list of cleanup actions (you create and manage this list with calls to tpm_cleanactionlistins and related functions), also allocate memory for cleanup action variables, which specify properties for individual actions. Again use tpm_varalloc.

    ade_id cleanupActionVarId = tpm_varalloc();
  3. Get a selection set of objects to be cleaned (the include set).
    ads_name ssObjsForCleanup;
    acutPrintf("\nSelect the objects to perform cleanup on.");
    acedSSGet(NULL, NULL, NULL, NULL, ssObjsForCleanup);

    Or create one.

    struct resbuf* pFilteredEntitySelectionRb = acutBuildList(
    RTDXF0, "LWPOLYLINE",
    8, "UtilityNetwork-Electric",
    0);
    ads_name ssObjsForCleanup;
    acedSSGet("X", NULL, NULL, pFilteredEntitySelectionRb, ssObjsForCleanup);
    acutRelRb(pFilteredEntitySelectionRb);

    You can also get a selection set of objects to be anchored (the anchor set). Anchored objects are not repositioned by the cleanup process, but remain fixed while others are repositioned around them.

    ads_name ssObjsToAnchor;
    acutPrintf("\nSelect the objects to serve as an anchor.");
    acedSSGet(NULL, NULL, NULL, NULL, ssObjsToAnchor);

    The acedSSGet function prompts the user to select objects and returns a selection set. This function can also be used with a resbuf to filter selected objects. Make sure to release selection sets when finished with them, using acedSSFree()

  4. Set cleanup variables using tpm_varset with the clean_var_id that you allocated in step 2. A few of these variables specify cleanup actions, but most of them specify how cleanup actions will be performed.
    // Set the cleanup variable "LINK_ERROR" for break crossing.
    char* pszConfigVarName = "LINK_ERROR";
    struct resbuf* pLinkErrorVarValRb = acutBuildList(
    RTSHORT, 2,
    0);
    int resultCode = tpm_varset(
    cleanupVarId,
    pszConfigVarName,
    pLinkErrorVarValRb);
    acutRelRb(pLinkErrorVarValRb);
    // Set the cleanup variable "INCLUDEOBJS_AUTOSELECT".
    // Must be included with a filtered selection set.
    pszConfigVarName = "INCLUDEOBJS_AUTOSELECT";
    struct resbuf* pIncludeObjsVarValRb = acutBuildList(
    RTSHORT, 0,
    0);
    resultCode = tpm_varset(
    cleanupVarId,
    pszConfigVarName,
    pIncludeObjsVarValRb);
    acutRelRb(pIncludeObjsVarValRb);
    // Set the cleanup variable "INCLUDEOBJS_LAYERS".
    // Must be included with a filtered selection set.
    pszConfigVarName = "INCLUDEOBJS_LAYERS";
    struct resbuf* pIncludeObjsLyrVarValRb = acutBuildList(
    RTSTR, "UtilityNetwork-Electric",
    0);
    resultCode = tpm_varset(
    cleanupVarId,
    pszConfigVarName,
    pIncludeObjsLyrVarValRb);
    acutRelRb(pIncludeObjsLyrVarValRb);

    Before setting cleanup variables, you can load a cleanup profile if you saved one previously, and in that way set many variables at once. Use tpm_cleanprofileload.

    resultCode = tpm_cleanprofileload(
    cleanupVarId,
    "C:\\profile.dpf");

    If you specify an explicit list of cleanup actions, note that those will be the only actions performed. Cleanup actions specified by the variables NODE_ERROR, LINK_ERROR, and GENERALIZE will be ignored, as well as any setting specific to them only, such as CORRIDOR's, which defines the tolerance for GENERALIZE.

    Using an action list is the best way to specify cleanup actions, because you can specify the order in which they execute, and you can include the same action more than once. Using variables to specify cleanup actions is an older technique, which is still supported for the sake of older scripts, but it is deprecated from AutoCAD Map 3D 6 onward.

    Note When you insert the Simplify Objects action (clean group type 128), it is always listed first, and you cannot insert it more than once.

    With an explicit list of cleanup actions, note that certain individual actions can have individual tolerance settings (and in some cases, other settings also). See Cleanup Action Variables. When you are about to insert an action into the action list, you can use tpm_varset with the action_var_id that you allocated in step 2 to set variables for this action before calling tpm_cleanactionlistins. You can continually reset and reuse the same set of cleanup action variables with each action that you insert.

    // Set CLEAN_TOL cleanup variable for simplify objects,(weeding).
    pszConfigVarName = "CLEAN_TOL";
    struct resbuf* pCleanTolVarValRb = acutBuildList(
    RTREAL, 2.0,
    0);
    resultCode = tpm_varset(
    cleanupActionVarId,
    pszConfigVarName,
    pCleanTolVarValRb);
    acutRelRb(pCleanTolVarValRb);

    Insert a cleanup action for simplify objects by specifying the cleanup variables id (real) returned by tpm_cleanalloc(), the index at which the item will be inserted into the list, the clean group type code, (see tpm_cleangrouptype for a list of types) and the cleanup action variable id (real) returned by tpm_varalloc().

    resultCode = tpm_cleanactionlistins(
    cleanupVarId,
    0,
    128,
    cleanupActionVarId);

    Insert an additional cleanup action for break crossing objects. The index position of -1 is for the last position.

    resultCode = tpm_cleanactionlistins(
    cleanupVarId,
    -1,
    2,
    cleanupActionVarId);

    At any point while you are setting cleanup variables, or after you have finished, you can save the current cleanup profile using tpm_cleanprofilesave.

    resultCode = tpm_cleanprofilesave(
    cleanupVarId,
    "C:\\profile.dpf");

    Note that saved profiles are XML files. You can view or edit them in a text editor as you can with saved queries (which are AutoLISP scripts). See Editing Query Files.

  5. Call tpm_cleaninit to add cleanup variables and the selection set of objects to clean to the cleanup model.
    resultCode = tpm_cleaninit(
    cleanupModelId,
    cleanupVarId,
    ssObjsForCleanup);

    If you have collected a selection set of objects to be anchored, first call tpm_cleaninitanchorset before calling tpm_cleaninit.

    resultCode = tpm_cleaninitanchorset(
    cleanupModelId,
    cleanupVarId,
    ssObjsForAnchor);

    The cleanup model is now complete.

To execute the cleanup

  1. Begin the cleanup process with tpm_cleanstart.
    resultCode = tpm_cleanstart(cleanupModelId);
  2. Execute cleanup actions (process cleanup groups) until cleanup is complete. With each cleanup group, with each error, mark and fix it.
    resultCode = tpm_cleangroupnext(cleanupModelId);
    if (resultCode == RTNORM){
    while (! (tpm_cleancomplete(cleanupModelId))){
    long lCleanErrors = 0;
    tpm_cleangroupqty(cleanupModelId, &lCleanErrors);
    for (int i = 0; i < lCleanErrors; i++){
    resultCode = tpm_cleanerrorcur(cleanupModelId, i);
    resultCode = tpm_cleanerrormark(cleanupModelId);
    resultCode = tpm_cleanerrorfix(cleanupModelId);
    }
    resultCode = tpm_cleangroupnext(cleanupModelId);
    }
    }
    else {
    acutPrintf("\nNothing to clean.");
    }
  3. Update the drawing with tpm_cleanend.
    resultCode = tpm_cleanend(cleanupModelId);

    Optional, To clear the cleanup model without updating the drawing, use tpm_cleancancel.

    resultCode = tpm_cleancancel(cleanupModelId);
  4. Free the cleanup model.
    resultCode = tpm_cleanfree(cleanupModelId);
  5. Free the selection set.
    resultCode = acedSSFree(ssObjsForCleanup);