// File: rurban[P]dgnlib/dgnwrite.cpp
// Function: DGNCreateMultiPointElem
DGNElemCore *DGNCreateMultiPointElem( DGNHandle hDGN, int nType, 
                                      int nPointCount, DGNPoint *pasVertices )

{
    DGNElemMultiPoint *psMP;
    DGNElemCore *psCore;
    DGNInfo *psDGN = (DGNInfo *) hDGN;
    int i;
    DGNPoint sMin, sMax;

    CPLAssert( nType == DGNT_LINE 
               || nType == DGNT_LINE_STRING
               || nType == DGNT_SHAPE
               || nType == DGNT_CURVE
               || nType == DGNT_BSPLINE_POLE );

    DGNLoadTCB( hDGN );

/* -------------------------------------------------------------------- */
/*      Is this too many vertices to write to a single element?         */
/* -------------------------------------------------------------------- */
    if( nPointCount > 101 )
    {
        CPLError( CE_Failure, CPLE_ElementTooBig, 
                  "Attempt to create %s element with %d points failed.\n"
                  "Element would be too large.",
                  DGNTypeToName( nType ), nPointCount );
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Allocate element.                                               */
/* -------------------------------------------------------------------- */
    psMP = (DGNElemMultiPoint *) 
        CPLCalloc( sizeof(DGNElemMultiPoint)
                   + sizeof(DGNPoint) * (nPointCount-2), 1 );
    psCore = &(psMP->core);

    DGNInitializeElemCore( hDGN, psCore );
    psCore->stype = DGNST_MULTIPOINT;
    psCore->type = nType;

/* -------------------------------------------------------------------- */
/*      Set multipoint specific information in the structure.           */
/* -------------------------------------------------------------------- */
    psMP->num_vertices = nPointCount;
    memcpy( psMP->vertices + 0, pasVertices, sizeof(DGNPoint) * nPointCount );

/* -------------------------------------------------------------------- */
/*      Setup Raw data for the multipoint section.                      */
/* -------------------------------------------------------------------- */
    if( nType == DGNT_LINE )
    {
        CPLAssert( nPointCount == 2 );

        psCore->raw_bytes = 36 + psDGN->dimension* 4 * nPointCount;

        psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1);

        DGNInverseTransformPointToInt( psDGN, pasVertices + 0, 
                                       psCore->raw_data + 36 );
        DGNInverseTransformPointToInt( psDGN, pasVertices + 1, 
                                       psCore->raw_data + 36
                                       + psDGN->dimension * 4 );
    }
    else
    {
        CPLAssert( nPointCount >= 2 );

        psCore->raw_bytes = 38 + psDGN->dimension * 4 * nPointCount;
        psCore->raw_data = (unsigned char*) CPLCalloc(psCore->raw_bytes,1);

        psCore->raw_data[36] = (unsigned char) (nPointCount % 256);
        psCore->raw_data[37] = (unsigned char) (nPointCount/256);

        for( i = 0; i < nPointCount; i++ )
            DGNInverseTransformPointToInt( psDGN, pasVertices + i, 
                                           psCore->raw_data + 38 
                                           + psDGN->dimension * i * 4 );
    }
    
/* -------------------------------------------------------------------- */
/*      Set the core raw data, including the bounds.                    */
/* -------------------------------------------------------------------- */
    DGNUpdateElemCoreExtended( hDGN, psCore );

    sMin = sMax = pasVertices[0];
    for( i = 1; i < nPointCount; i++ )
    {
        sMin.x = MIN(pasVertices[i].x,sMin.x);
        sMin.y = MIN(pasVertices[i].y,sMin.y);
        sMin.z = MIN(pasVertices[i].z,sMin.z);
        sMax.x = MAX(pasVertices[i].x,sMax.x);
        sMax.y = MAX(pasVertices[i].y,sMax.y);
        sMax.z = MAX(pasVertices[i].z,sMax.z);
    }

    DGNWriteBounds( psDGN, psCore, &sMin, &sMax );
    
    return psCore;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0x11190
cmpl $0x65, -0x18(%rbp)
jle 0x131b4
movl -0x14(%rbp), %edi
callq 0xc2d0
movq %rax, %rcx
movl -0x18(%rbp), %r8d
movl $0x3, %edi
movl $0x1, %esi
leaq 0x75ec(%rip), %rdx      # 0x1a78c
movb $0x0, %al
callq 0x5740
movq $0x0, -0x8(%rbp)
jmp 0x135d5
movl -0x18(%rbp), %eax
subl $0x2, %eax
cltq
imulq $0x18, %rax, %rdi
addq $0x88, %rdi
movl $0x1, %esi
callq 0x2fc0
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x135f0
movq -0x30(%rbp), %rax
movl $0x2, 0xc(%rax)
movl -0x14(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x14(%rax)
movl -0x18(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x50(%rax)
movq -0x28(%rbp), %rdi
addq $0x58, %rdi
movq -0x20(%rbp), %rsi
movslq -0x18(%rbp), %rax
imulq $0x18, %rax, %rdx
callq 0x2240
cmpl $0x3, -0x14(%rbp)
jne 0x132b1
movq -0x38(%rbp), %rax
movl 0x20018(%rax), %ecx
shll $0x2, %ecx
imull -0x18(%rbp), %ecx
addl $0x24, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x30(%rbp), %rax
movslq 0x40(%rax), %rdi
movl $0x1, %esi
callq 0x2fc0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x30(%rbp), %rax
movq 0x48(%rax), %rdx
addq $0x24, %rdx
callq 0x10fd0
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x18, %rsi
movq -0x30(%rbp), %rax
movq 0x48(%rax), %rdx
addq $0x24, %rdx
movq -0x38(%rbp), %rax
movl 0x20018(%rax), %eax
shll $0x2, %eax
cltq
addq %rax, %rdx
callq 0x10fd0
jmp 0x1336f
movq -0x38(%rbp), %rax
movl 0x20018(%rax), %ecx
shll $0x2, %ecx
imull -0x18(%rbp), %ecx
addl $0x26, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x30(%rbp), %rax
movslq 0x40(%rax), %rdi
movl $0x1, %esi
callq 0x2fc0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x48(%rax)
movl -0x18(%rbp), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movb %dl, %cl
movq -0x30(%rbp), %rax
movq 0x48(%rax), %rax
movb %cl, 0x24(%rax)
movl -0x18(%rbp), %eax
movl $0x100, %ecx            # imm = 0x100
cltd
idivl %ecx
movb %al, %cl
movq -0x30(%rbp), %rax
movq 0x48(%rax), %rax
movb %cl, 0x25(%rax)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x1336d
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
movslq -0x3c(%rbp), %rax
imulq $0x18, %rax, %rax
addq %rax, %rsi
movq -0x30(%rbp), %rax
movq 0x48(%rax), %rdx
addq $0x26, %rdx
movq -0x38(%rbp), %rax
movl 0x20018(%rax), %eax
imull -0x3c(%rbp), %eax
shll $0x2, %eax
cltq
addq %rax, %rdx
callq 0x10fd0
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x13320
jmp 0x1336f
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x12f50
movq -0x20(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x70(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x68(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x70(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x48(%rbp)
movl $0x1, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x135b8
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm1
movsd -0x58(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x133fa
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x78(%rbp)
jmp 0x13404
movsd -0x58(%rbp), %xmm0
movsd %xmm0, -0x78(%rbp)
movsd -0x78(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm1
movsd -0x50(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x13448
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x80(%rbp)
jmp 0x13452
movsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x80(%rbp)
movsd -0x80(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm1
movsd -0x48(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x13499
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x88(%rbp)
jmp 0x134a6
movsd -0x48(%rbp), %xmm0
movsd %xmm0, -0x88(%rbp)
movsd -0x88(%rbp), %xmm0
movsd %xmm0, -0x48(%rbp)
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
ucomisd -0x70(%rbp), %xmm0
jbe 0x134ea
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x90(%rbp)
jmp 0x134f7
movsd -0x70(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
ucomisd -0x68(%rbp), %xmm0
jbe 0x1353d
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x98(%rbp)
jmp 0x1354a
movsd -0x68(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movsd -0x98(%rbp), %xmm0
movsd %xmm0, -0x68(%rbp)
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
ucomisd -0x60(%rbp), %xmm0
jbe 0x13590
movq -0x20(%rbp), %rax
movslq -0x3c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0xa0(%rbp)
jmp 0x1359d
movsd -0x60(%rbp), %xmm0
movsd %xmm0, -0xa0(%rbp)
movsd -0xa0(%rbp), %xmm0
movsd %xmm0, -0x60(%rbp)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x133b6
movq -0x38(%rbp), %rdi
movq -0x30(%rbp), %rsi
leaq -0x58(%rbp), %rdx
leaq -0x70(%rbp), %rcx
callq 0x13630
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)