// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rcx, %r15
movl %edx, %r13d
movl %esi, %ebp
movq %rdi, %rbx
callq 0xa500
cmpl $0x66, %r13d
jl 0xb4b7
movl %ebp, %edi
callq 0x7d82
leaq 0x4723(%rip), %rdx      # 0xfbc0
xorl %ebx, %ebx
pushq $0x3
popq %rdi
pushq $0x1
popq %rsi
movq %rax, %rcx
movl %r13d, %r8d
xorl %eax, %eax
callq 0x439c
jmp 0xb635
leal -0x2(%r13), %eax
cltq
imulq $0x18, %rax, %rdi
addq $0x88, %rdi
pushq $0x1
popq %r12
movq %r12, %rsi
callq 0x2c6c
movq %rax, %r14
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
movups %xmm0, 0x20(%rax)
movups %xmm0, 0x30(%rax)
orl $-0x1, (%rax)
movups %xmm0, 0x40(%rax)
movabsq $0x2ffffffff, %rax      # imm = 0x2FFFFFFFF
movq %rax, 0x8(%r14)
movl %ebp, 0x14(%r14)
movl %r13d, 0x50(%r14)
leaq 0x58(%r14), %rdi
movslq %r13d, %rax
movq %rax, 0x8(%rsp)
imulq $0x18, %rax, %rdx
movq %r15, %rsi
callq 0x2230
movl 0x20018(%rbx), %eax
imull %r13d, %eax
shll $0x2, %eax
cmpl $0x3, %ebp
movq %rbx, (%rsp)
jne 0xb647
addl $0x24, %eax
movl %eax, 0x40(%r14)
movslq %eax, %rdi
pushq $0x1
popq %rsi
callq 0x2c6c
movq %rax, 0x48(%r14)
leaq 0x24(%rax), %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0xa44d
leaq 0x18(%r15), %rsi
movq %rbx, %rdi
movq %r14, %rbx
movq 0x48(%r14), %rax
movslq 0x20018(%rdi), %rcx
leaq (%rax,%rcx,4), %rdx
addq $0x24, %rdx
callq 0xa44d
movq %rbx, %rsi
callq 0xb380
movq 0x10(%r15), %rax
movq %rax, 0x20(%rsp)
movups (%r15), %xmm0
movaps %xmm0, 0x10(%rsp)
movups (%r15), %xmm0
movaps %xmm0, 0x30(%rsp)
movq 0x10(%r15), %rax
movq %rax, 0x40(%rsp)
movsd 0x30(%rsp), %xmm2
movsd 0x10(%rsp), %xmm0
movupd 0x38(%rsp), %xmm3
movupd 0x18(%rsp), %xmm1
addq $0x20, %r15
movq (%rsp), %rdi
movq 0x8(%rsp), %rax
cmpq %rax, %r12
jge 0xb611
movsd -0x8(%r15), %xmm4
movapd %xmm4, %xmm5
minsd %xmm2, %xmm5
maxsd %xmm0, %xmm4
movupd (%r15), %xmm6
movapd %xmm6, %xmm7
minpd %xmm3, %xmm7
maxpd %xmm1, %xmm6
incq %r12
addq $0x18, %r15
movapd %xmm4, %xmm0
movapd %xmm5, %xmm2
movapd %xmm6, %xmm1
movapd %xmm7, %xmm3
jmp 0xb5d0
leaq 0x30(%rsp), %rdx
movupd %xmm3, 0x8(%rdx)
leaq 0x10(%rsp), %rcx
movupd %xmm1, 0x8(%rcx)
movsd %xmm2, (%rdx)
movsd %xmm0, (%rcx)
movq %rbx, %rsi
callq 0xb6bf
movq %rbx, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
addl $0x26, %eax
movl %eax, 0x40(%r14)
movslq %eax, %rdi
pushq $0x1
popq %rsi
callq 0x2c6c
movq %rax, 0x48(%r14)
movb %r13b, 0x24(%rax)
movl $0x100, %ecx            # imm = 0x100
movl %r13d, %eax
cltd
idivl %ecx
movq %r14, %rbx
movq 0x48(%r14), %rcx
movb %al, 0x25(%rcx)
xorl %r14d, %r14d
testl %r13d, %r13d
cmovlel %r14d, %r13d
shlq $0x2, %r13
movq %r15, %rbp
cmpq %r14, %r13
je 0xb57f
movq 0x48(%rbx), %rax
movq (%rsp), %rdi
movl 0x20018(%rdi), %ecx
imull %r14d, %ecx
movslq %ecx, %rcx
leaq (%rax,%rcx), %rdx
addq $0x26, %rdx
movq %rbp, %rsi
callq 0xa44d
addq $0x4, %r14
addq $0x18, %rbp
jmp 0xb687